"""
/*
 * Copyright 2011 OpenWAF.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
 """

import sys



from JavaLangAST import Annotation
from JavaLangAST import AnnotationMethod
from JavaLangAST import AnnotationType
from JavaLangAST import ArrayInitializer
from JavaLangAST import Block
from JavaLangAST import Class
from JavaLangAST import ClassBody
from JavaLangAST import ClassCreatorRest
from JavaLangAST import ClassOrInterfaceType
from JavaLangAST import CompilationUnit
from JavaLangAST import Creator
from JavaLangAST import CreatorArray
from JavaLangAST import CreatorInner
from JavaLangAST import ElementValuePair
from JavaLangAST import Enum
from JavaLangAST import EnumBody
from JavaLangAST import EnumConstant
from JavaLangAST import ExArguments
from JavaLangAST import ExArray
from JavaLangAST import ExArrayIndex
from JavaLangAST import ExCastExpression
from JavaLangAST import ExClass
from JavaLangAST import ExCreator
from JavaLangAST import ExDot
from JavaLangAST import ExIdentifier
from JavaLangAST import ExInnerCreator
from JavaLangAST import ExLiteral
from JavaLangAST import ExOperator
from JavaLangAST import ExParExpression
from JavaLangAST import ExPart
from JavaLangAST import ExPrimitiveType
from JavaLangAST import ExSuper
from JavaLangAST import ExThis
from JavaLangAST import ExType
from JavaLangAST import ExTypeArguments
from JavaLangAST import ExVoid
from JavaLangAST import Expression
from JavaLangAST import Field
from JavaLangAST import Import
from JavaLangAST import InnerCreator
from JavaLangAST import Interface
from JavaLangAST import InterfaceField
from JavaLangAST import InterfaceMethod
from JavaLangAST import Literal
from JavaLangAST import LocalVariableDeclaration
from JavaLangAST import Method
from JavaLangAST import Modifier
from JavaLangAST import OprAdditive
from JavaLangAST import OprAssign
from JavaLangAST import OprBinary
from JavaLangAST import OprEquality
from JavaLangAST import OprInstanceOf
from JavaLangAST import OprLogical
from JavaLangAST import OprMultiplicative
from JavaLangAST import OprPostfix
from JavaLangAST import OprRelational
from JavaLangAST import OprShift
from JavaLangAST import OprTernary
from JavaLangAST import OprUnary
from JavaLangAST import Parameter
from JavaLangAST import PrimitiveType
from JavaLangAST import QualifiedName
from JavaLangAST import StaticBlock
from JavaLangAST import StmtAssert
from JavaLangAST import StmtBlock
from JavaLangAST import StmtBreak
from JavaLangAST import StmtCatch
from JavaLangAST import StmtContinue
from JavaLangAST import StmtDoWhile
from JavaLangAST import StmtExp
from JavaLangAST import StmtExplicitConstructorInvocation
from JavaLangAST import StmtFor
from JavaLangAST import StmtIf
from JavaLangAST import StmtLabel
from JavaLangAST import StmtLocalVariableDeclaration
from JavaLangAST import StmtReturn
from JavaLangAST import StmtSemicolon
from JavaLangAST import StmtSwitch
from JavaLangAST import StmtSwitchBlock
from JavaLangAST import StmtSynch
from JavaLangAST import StmtThrow
from JavaLangAST import StmtTry
from JavaLangAST import StmtWhile
from JavaLangAST import Type
from JavaLangAST import TypeArgument
from JavaLangAST import TypeParameter
from JavaLangAST import VariableDeclarator
from LiteralReader import readLiteral
import Semantic
from Tokenizer import Token
from Tokenizer import TokenStream
from Tokenizer import tokenize
import datetime
import os
from xml.dom.minidom import parse
from xml.dom.minidom import parseString
import copy
import Compiler
from ConfigReader import WAFConfig
from idlelib.AutoComplete import ID_CHARS
ws_char = [chr(0x0A), chr(0x20), chr(0x09), chr(0x0C), chr(0x0D)]
class SCompilationUnit:
    def __init__(self):
        self.filepath = None
        self.package = None
        self.imported = {}
        self.delcs = []
        self.annotations = None
        self.importsprocessed = False
    def processImports(self):
        if self.importsprocessed == True:return
        self.imported = SHelper.getImportedAll(self.imported, self.package)
        self.importsprocessed = True


class SPackage:
    def __init__(self):
        self.name = ""
        self.subpackages = {}
        self.types = {}
        self.prototype = None        
    def getPrototype(self):
        return self.prototype
     
        

class SModifier:
    PUBLIC = 0x1
    PRIVATE = 0x2
    PROTECTED = 0x3
    STATIC = 0x4
    ABSTRACT = 0x5
    FINAL = 0x6
    NATIVE = 0x7
    SYNCHRONIZED = 0x8
    TRANSIENT = 0x9
    VOLATILE = 0xA
    STRICTFP = 0xB
    DEFAULT = 0xC

    @staticmethod
    def toConstant(st):
        if st == "public":       return SModifier.PUBLIC
        if st == "private":      return SModifier.PRIVATE
        if st == "protected":    return SModifier.PROTECTED
        if st == "abstract":     return SModifier.ABSTRACT
        if st == "final":           return SModifier.FINAL
        if st == "native":       return SModifier.NATIVE
        if st == "static":       return SModifier.STATIC
        if st == "strictfp":     return SModifier.STRICTFP
        if st == "synchronized": return SModifier.SYNCHRONIZED
        if st == "transient":    return SModifier.TRANSIENT
        if st == "volatile":     return SModifier.VOLATILE
        raise StandardError("[CRITICAL]Unkwon modifier" + st)
class HasModifiers(object):
    def __init__(self):
        self.modifiers = None
        self.annotations = None
    def isPublic(self):return SHelper.containsModifier(self.modifiers, SModifier.PUBLIC)
    def isPrivate(self):return SHelper.containsModifier(self.modifiers, SModifier.PRIVATE)
    def isProtected(self):return SHelper.containsModifier(self.modifiers, SModifier.PROTECTED)
    def isAbstract(self):return SHelper.containsModifier(self.modifiers, SModifier.ABSTRACT)
    def isFinal(self):return SHelper.containsModifier(self.modifiers, SModifier.FINAL)
    def isNative(self):return SHelper.containsModifier(self.modifiers, SModifier.NATIVE)
    def isStatic(self):return SHelper.containsModifier(self.modifiers, SModifier.STATIC)
    def isDefault(self):return SHelper.containsModifier(self.modifiers, SModifier.DEFAULT)
    def getAnnotations(self):return self.annotations
    def setAnnotations(self,values):
        self.annotations=values
    def getAnnotation(self,name):
        if self.annotations==None:return None
        for v in self.annotations:
            if v.name==name:
                return v
        return None                    
    def getModifiers(self):return self.modifiers
    def setModifiers(self, modifiers):self.modifiers = modifiers
    def addModifier(self, mod):
        if self.modifiers == None:
            print "Modifiers is null"
            some_method()
        if mod in self.modifiers:
            return
        self.modifiers.append(mod)
    def hasAnyOfTheseModifiers(self, mods):
        for m in mods:
            if m in self.modifiers:
                return True
        return False
    def removeModifier(self, mod):
        if self.modifiers == None:return
        if SHelper.containsModifier(self.modifiers, mod):
            self.modifiers.remove(mod)
            
        


class STypeDeclaration(HasModifiers):
    INNER = 0
    OUTER = 1
    CLSID_COUNTER = 0
    def __init__(self):
        HasModifiers.__init__(self)
        self.field_index = 0
        self.declclazz = None
        self.name = None
        self.fullname = None
        self.annotations = []
        self.package = None
        self.inner = False
        self.scu = None
        self.processed = False
        self.mytype = None
        self.methods = []
        self.fields = {}
        self.innerMembers = []
        self.typepars = None
        self._typepars = None
        self.implements = []
        self.implclass = []
        self.extends = []
        self.exclass = []
        ### following fields are used while generating jscode
        self.clsid = STypeDeclaration.CLSID_COUNTER
        STypeDeclaration.CLSID_COUNTER += 1
        self.prototype = None        
        self.symbols = {} #this is to make sure that we are using unique properties  while allocating property name        
        self.exmembers = []
        self.inheritance_depth = None
        self.last_symbol_used = 0
        self.static_blocks = []
        self.instance_static_blocks = []
        self.static_code_function_name = None
        self.refs = []
        self.model_class=False
        self.controller_class=False        
    def isControllerClass(self):
        return self.controller_class
    def isModelClass(self):
        return self.model_class
    def collectTypes(self, classes):
        for m in self.innerMembers:
            if isinstance(m, STypeDeclaration):
                classes.append(m)
                m.collectTypes(classes)
            else:
                print "Error"
                some_method()        
    def addStaticBlock(self, block):
        if block.static == True:
            self.static_blocks.append(block)
        else:
            self.instance_static_blocks.append(block)
    def hasStaticBlocks(self):
        return len(self.static_blocks) > 0 or len(self.instance_static_blocks) > 0
    def hasStaticStaticBlocks(self):
        return len(self.static_blocks) > 0
    def hasInstanceStaticBlocks(self):
        return len(self.instance_static_blocks) > 0
    def getInstanceIds(self, data):
        data.append(self.clsid)
        if self.exclass != None :
            for ex in self.exclass:
                ex.getInstanceIds(data)
        if self.implclass != None :
            for ex in self.implclass:
                ex.getInstanceIds(data)
    def getFullSymbolToUse(self, base):
        count = 0
        s = base
        while self.symbols.has_key(s):
            s = base + "_" + str(count)
            count += 1
        self.symbols[s] = 1
        return s
    def getShortSymbolToUse(self):
        self.last_symbol_used += 1
        s = "s" + str(self.last_symbol_used)
        while self.symbols.has_key(s) or self.symbols.has_key(s):
            self.last_symbol_used += 1
            s = "s" + str(self.last_symbol_used)
        self.symbols[s] = 1
        return s
        
    def addSymbol(self, name):
        if self.symbols.has_key(name):
            print  "Error . Tyring to use same symbol again"
            some_method()#just to cause exception to print stack trace
        self.symbols[name] = 1
    def canIUseThisSymbol(self, name):
        return not self.symbols.has_key(name)
    


    def getCLSID(self):
        return self.clsid;
    def getPrototype(self):
        return self.prototype    
   
    def getDegreeWithThis(self, atd):
        if self.fullname == atd.fullname:
            return 0
        for ex in self.exclass:
            d = ex.getDegreeWithThis(atd)
            if d >= 0:
                return d + 1
        for ex in self.implclass:
            d = ex.getDegreeWithThis(atd)
            if d >= 0:
                return d + 1
        if atd.fullname == SGlobal.objclass.fullname:
            return 100#just to have something i dont think this will mater a lot
        return -1

    def getDeclaringClass(self):
        return self.declclazz
    def setDeclaringClass(self, clazz):
        self.declclazz = clazz
    def processTypeparameters(self):
        if self.typepars != None:
            for tp in self.typepars:
                SHelper.processTypeParameter(tp, self, None)
        self.processTypePars()
    def addExtendedType(self, t):
        self.extends.append(t)
    def getExtendedTypes(self):
        return self.extends
    def getExtendedClasses(self):
        return self.exclass
    def addImplemenetedType(self, t):
        self.implements.append(t)
    def getImplementedTypes(self):
        return self.implements
    def getImplementedClasses(self):
        return self.implclass
    def setTypepars(self, typepars):
        self.typepars = typepars
        tpars = typepars
        if tpars != None:
            index = 0
            for tp in tpars:
                tp.index = index
                tp.forclass = self
                tp.formethod = None
                index += 1
    def processTypePars(self):
        if self.typepars == None:return
        self._typepars = []
        for tpar in self.typepars:
            ta = TypeArgument()
            ta.isany = False
            t = self.convertTypeParameterToTypePass1(tpar)
            ta.typ = t
            self._typepars.append(ta)
        for t in self._typepars:
            self.convertTypeParameterToTypePass2(ta.typ)
            
        
    def getTypepars(self):
        return self.typepars
    def getTypeParameterWithName(self, name):
        if self.typepars != None:
            for t in self.typepars:
                if t.name.data == name: return t
        if self.declclazz != None:
            return self.declclazz.getTypeParameterWithName(name)
        return None
    def isClass(self):return False
    def isEnum(self):return False
    def isInterface(self):return False
    def isAnnotationType(self):return False
    def getMyType(self):
        return self.mytype
    def setMyType(self, t):
        self.mytype = t
    def getName(self):
        return self.name
    def setName(self, name):
        self.name = name
    def getPackage(self):
        return self.package
    def setPackage(self, package):
        self.package = package
    def getFullname(self):
        return self.fullname
    def setFullname(self, name):
        self.fullname = name
    def getImports(self):
        return self.scu.imported
    def isInner(self):
        return self.inner
    def setInner(self, value):
        self.inner = value
    def setCompilationUnit(self, scu):
        self.scu = scu
    def getCompilationUnit(self):
        return self.scu
    def isProcessed(self):
        return self.processed
    def setProcessed(self, value):
        self.processed = value
    def getAnnotations(self):
        return self.annotations
    def addAnnotation(self, anno):
        self.annotations.append(anno)
    def addField(self, f):
        if self.fields.has_key(f.name):
            raise CompilerError("Duplicate Variable Declaration", "", None)
        self.fields[f.name] = f
    def getField(self, name):
        if self.fields.has_key(name):
            return self.fields[name]
        return None
    def addMethod(self, method):
        self.methods.append(method)
    def getAllPossibleMethods(self, name, args, method_type_args):
        methods = []
        for m in self.methods:
            if m.name != name:continue
            d = m.matchArgsAndGetDegree(args, self._typepars, self, method_type_args)
            if d != None:
                methods.append([d, m])
        for ex in self.exclass:
            exm = ex.getAllPossibleMethods(name, args, method_type_args)
            if exm != None and len(exm) > 0:
                methods = methods + exm
        for ex in self.implclass:
            exm = ex.getAllPossibleMethods(name, args, method_type_args)
            if exm != None and len(exm) > 0:
                methods = methods + exm
        return methods
    def getMethod(self, name, args, method_type_args):
        for m in self.methods:
            if m.name == name:
                if m.matchArgs(args, self._typepars, self, method_type_args):
                    return m
        if self.exclass != None:
            for ex in self.exclass:
                m = ex.getMethod(name, args, method_type_args)
                if m != None:return m
        return None
    def getMethods(self):
        return self.methods
    def isClassInnerToMe(self, clazz):
        for m in self.innerMembers:
            if m == clazz:return True
        return False
    def isClassOuterToMe(self, clazz):
        if self.declclazz == None:return #TODO:actually we shoudl throgh an exception here
        if self == clazz:return False
        if self.declclazz == clazz:return True
        return self.declclazz.isClassOuterToMe(clazz)
    def getInnerMember(self, name):
        #TODO:Access control is not considered
        for m in self.innerMembers:
            if m.name == name:
                return m
        for ex in self.exclass:
            r = ex.getInnerMember(name)
            if r != None:return r
        for i in self.implclass:
            r = i.getInnerMember(name)
            if r != None:return r
        return None
    def getOuterMember(self, name):
        if self.declclazz == None or self.declclazz == self:return None
        #if self.clazz.hasTypeparameterWithName(name):
        #    return self.clazz.getTypeparameterWithName(name)
        if isinstance(self.declclazz, STypeDeclaration):
            r = self.declclazz.getInnerMember(name)
            if r != None:return r
            return self.declclazz.getOuterMember(name)
        else:
            m = self.declclazz.clazz.getInnerMember(name)
            if m != None:return m
            return self.declclazz.clazz.getOuterMember(name)
    def addInnerMember(self, m):
        self.innerMembers.append(m)
        m.setDeclaringClass(self)
    def getIneheritanceLevel(self):
        if self.isClass() or self.isEnum():
            if self.exclass != None and len(self.exclass) == 1:
                return self.exclass[0].getIneheritanceLevel() + 1
            return 1
        else:
            return 1


    def countInheritanceDepth(self):
        if self.inheritance_depth != None:return
        depth = 0
        for m in self.exmembers:
            if m.level > depth:depth = m.level
        self.inheritance_depth = depth + 1
    def getMethodWithThisAccess(self, name, args, only_static, method_type_args, accessing_class):
        self.countInheritanceDepth()
        for depth in range(self.inheritance_depth + 1):
            for m in self.exmembers:
                if not isinstance(m, ExMethod):continue
                if m.level != depth:continue
                if m.method.name != name:continue
                if len(m.pars) != len(args):continue
                if SHelper.canIAccessYou(m.method, accessing_class, only_static) and m.matchArgs(args, self._typepars, self, method_type_args):
                    return m
        all_degrees = []
        for m in self.exmembers:
            if not isinstance(m, ExMethod):continue
            if not m.method.name == name:continue
            if not SHelper.canIAccessYou(m.method, accessing_class, only_static):continue
            if len(m.pars) != len(args):continue
            d = m.matchArgsAndGetDegree(args, self._typepars, self, method_type_args)
            if d != None:
                all_degrees.append([d, m])
        
        no_of_methods = len(all_degrees)
        if no_of_methods == 0:
            #TODO:exception her
            return None
        if no_of_methods == 1:return all_degrees[0][1]
        minda = []
        for i in range(len(args)):minda.append(-1)
        SHelper.getMinDegreeArray(all_degrees, 0, minda, len(args))
        mind_methods = []
        for i in range(0, no_of_methods):
            if SHelper.compareDegreeArray(all_degrees[i][0], minda, len(args)):
                m = all_degrees[i][1]
                mind_methods.append(all_degrees[i][1])
        if len(mind_methods) == 1:
            return mind_methods[0]
        min_level = 100000
        for m in mind_methods:
            if m.level < min_level:min_level = m.level
        final_methods = []
        for m in mind_methods:
            if m.level == min_level:
                final_methods.append(m)
        if len(final_methods) == 1:
            return final_methods[0]
        return None        
        #print "Unexpected", name, args, self.fullname, some_method()
    
    def getFieldWithThisAccess(self, name, only_static, accessing_class):        
        #since interface fields are always public so no need to check anything
        self.countInheritanceDepth()
        for depth in range(self.inheritance_depth + 1):
            for m in self.exmembers:
                if not isinstance(m, ExField):continue
                if m.level != depth:continue
                if m.field.name != name:continue
                if SHelper.canIAccessYou(m.field, accessing_class, only_static):
                    return m
        for im in self.innerMembers:
            if im.name == name:
                return im
        """
        if self.isEnum():
            for f in self.fields:
                f=self.fields[f]
                if f.name==name:
                    return f
        """                
        return None
        """
        if self.fields.has_key(name):
            f = self.fields[name]
            if SHelper.canIAccessYou(f, accessing_class, only_static):
                return f
        for ex in self.exclass:
            f = ex.getFieldWithThisAccess(name, only_static, accessing_class)
            if f != None:return f
        for ifc in self.implclass:
            f = ifc.getFieldWithThisAccess(name, only_static, accessing_class)
            if f != None:return f
        """
        return None
    def getDepthRelativeToThis(self, target):
        if self == target:return 0
        if self.getDegreeWithThis(target) != -1: return 0
        d = self.declclazz
        if d == None:
            print self.declclazz
            print self.fullname , target.fullname
            print "Parent Target Not Found"
            print "UnExpected", some_method()
        if isinstance(d, STypeDeclaration):
            return d.getDepthRelativeToThis(target) + 1
        elif isinstance(d, SMethod):
            return d.clazz.getDepthRelativeToThis(target) + 1
        else:
            print "Not Handled"
            some_method()
                 
    def getFieldFromContainerClass(self, name, only_static, accessing_class):
        d = self.declclazz
        if d == None:return None
        if isinstance(d, STypeDeclaration):
            r = d.getFieldWithThisAccess(name, only_static, accessing_class)
            if r != None:return r
            return d.getFieldFromContainerClass(name, only_static, accessing_class)
        elif isinstance(d, SMethod):
            d = d.clazz
            r = d.getFieldWithThisAccess(name, only_static, accessing_class)
            if r != None:return r
            return d.getFieldFromContainerClass(name, only_static, accessing_class)
        else:
            print "Not Handled"
            some_method()
        return None
    def getMethodFromContainerClass(self, name, args, only_static, accessing_class):
        d = self.declclazz
        if d == None:return None
        if isinstance(d, STypeDeclaration):
            r = d.getMethodWithThisAccess(name, args, only_static, None, accessing_class)
            if r != None:return r
            return d.getMethodFromContainerClass(name, args, only_static, accessing_class)
        elif isinstance(d, SMethod):
            d = d.clazz
            r = d.getMethodWithThisAccess(name, args, only_static, None, accessing_class)
            if r != None:return r
            return d.getMethodFromContainerClass(name, args, only_static, accessing_class)
        else:
            print "Not Handled 575/2024"
            some_method()
        return None

    def processFields(self):
        for f in self.fields:            
            f = self.fields[f]
            if f.getAnnotation("EnsureIdentifier"):
                if not self.canIUseThisSymbol(f.name):
                    raise Exception("Can not ensure the symbol "+f.name+" "+self.fullname) 
                self.addSymbol(f.name)
                f.js_name=f.name
            else:                                    
                if WAFConfig.isMinify():
                    f.js_name= self.getShortSymbolToUse()                
                else:
                    f.js_name = self.getFullSymbolToUse(f.getName())    
            SHelper.processType(f.type, self, None)

    def processMethods(self):
        for m in self.methods:
            tpars = m.typepars
            if tpars != None:
                index = 0
                for tp in tpars:
                    SHelper.processTypeParameter(tp, self, m)
                    tp.index = index
                    tp.forclass = None
                    tp.formethod = m
                    index += 1
            m.processTypeparameters()
            if m.rettype != None:
                SHelper.processType(m.rettype, self, m)
            for p in m.pars:
                SHelper.processType(p.typ, self, m)


    def processInnerMembers(self):
        for i in self.innerMembers:
            if i.isClass():
                SHelper.processSClass(i)
            elif i.isInterface():
                SHelper.processSInterface(i)
            elif i.isEnum():
                SHelper.processSEnum(i)
            else:
                print SHelper.ttos(i), " not processed "
                some_method()
    def convertTypeParameterToTypePass2(self, t):
        if not SHelper.isTypeParameterRec(t):
            return  t
        if t.coit != None:
            clz = t.coit.clazz
            if isinstance(clz, TypeParameter):
                tp = clz
                tp_clz = None
                if tp.forclass != None:
                    tp_clz = tp.forclass
                else:
                    tp_clz = tp.formethod
                return tp_clz._typepars[tp.index]
            #Type argument has to be there
            n_typeargs = []
            for arg in t.coit.typeargs:
                atype = None
                if arg.isany == True:
                    if arg.extends == None and arg.superclass == None:
                        atype = SGlobal.objclass.mytype
                    elif arg.extends != None:
                        atype = arg.extends
                    else:
                        atype = arg.superclass
                    arg.superclass
                else:
                    if arg.typ == None:
                        print "UnExpected", some_method()
                    atype = arg.typ
                    if arg.extends != None or arg.superclass != None:
                        print "UnExpected", some_method()
                _arg = self.convertTypeParameterToTypePass2(atype)
                n_typeargs.append(_arg)
            t.coit.typeargs = n_typeargs
        else:
            #This should have bounds
            n_bounds = []
            for b in t.bounds:
                _b = self.convertTypeParameterToTypePass2(b)
                n_bounds.append(_b)
            t.bounds = n_bounds
        return t
                
            
        
    def convertTypeParameterToTypePass1(self, tp):
        if not isinstance(tp, TypeParameter):
            print "UnExpected"
            some_method()
        if tp.bound == None:
            return SGlobal.objclass.mytype
        if len(tp.bound) == 1:
            #it has single bound
            b = tp.bound[0]
            if SHelper.isTypeParameter(b):
                # and that is another type , you can have another type paramater as multiple bounds 
                rt = Type()
                rt.bounds = []
                rt.bounds.append(b)
                return rt
            else:
                return b
        rt = Type()
        rt.bounds = []
        for b in tp.bound:
            rt.bounds.append(b)
        return rt
            
        
    def mapAndConvertType(self, type, targs, source_class , method_args, source_method):
        if source_class == None:print "UnExpected" , some_method()
        if not SHelper.isTypeParameterRec(type):return type
        ut = Type()
        if SHelper.isTypeParameter(type):
            ttype = None
            if type.coit.clazz.forclass != None and targs != None and source_class == type.coit.clazz.forclass:
                targ = targs[type.coit.clazz.index]
                if targ.typ != None:ttype = targ.typ
                elif targ.extends != None:ttype = targ.extends
                elif targ.superclass != None:ttype = targ.superclass
                else:
                    if targ.isany == True:ttype = SGlobal.objclass.mytype
                    else: print "Not Handled", some_method()
            elif type.coit.clazz.formethod != None and method_args != None and type.coit.clazz.formethod == source_method.method:
                targ = method_args[type.coit.clazz.index]
                if targ.typ != None:ttype = targ.typ
                elif targ.extends != None:ttype = targ.extends
                elif targ.superclass != None:ttype = targ.superclass
                else:
                    if targ.isany == True:ttype = SGlobal.objclass.mytype
                    else: print "Not Handled", some_method()
            else:
                if type.coit.clazz.forclass != None:
                    ttype = type.coit.clazz.forclass._typepars[type.coit.clazz.index].typ
                else: 
                    ttype = type.coit.clazz.formethod._typepars[type.coit.clazz.index].typ
                #ttype=source_class._typepars[type.coit.clazz.index].typ
            if SHelper.isTypeParameter(ttype):
                tp = None
                if source_method != None:
                    tp = source_method.getTypeParameterWithNameNonRec(ttype.coit.fullname)
                if tp == None:
                    tp = self.getTypeParameterWithName(ttype.coit.fullname)
                if tp == None:
                    print "Type Parameter not found", ttype.coit.fullname
                    some_method()
                ut.coit = ClassOrInterfaceType()
                ut.coit.fullname = tp.name
                ut.coit.clazz = tp 
            else:
                ut.coit = ClassOrInterfaceType()
                ut.coit.fullname = ttype.coit.fullname
                ut.coit.clazz = ttype.coit.clazz
                ut.coit.typeargs = ttype.coit.typeargs
                if ttype.coit.next != None:
                    ut.coit.next = self.mapAndConvertType(ttype.coit.next, targs, source_class , method_args, source_method)
        else:
            ut.coit = ClassOrInterfaceType()
            ut.coit.fullname = type.coit.fullname
            ut.coit.clazz = type.coit.clazz
            ut.coit.typeargs = type.coit.typeargs
            if type.coit.next != None:
                ut.coit.next = self.mapAndConvertType(type.coit.next, targs, source_class , method_args, source_method)
        if ut.coit.typeargs == None or len(ut.coit.typeargs) == 0:
            return ut
        u_typeargs = [] 
        for targ in ut.coit.typeargs:
            if SHelper.isTypeParameterRec(targ):
                m_targ = TypeArgument()
                if targ.typ != None:
                    m_targ.typ = self.mapAndConvertType(targ.typ, targs, source_class, method_args, source_method)
                if targ.extends != None:
                    m_targ.extends = self.mapAndConvertType(targ.extends, targs, source_class, method_args, source_method)
                if targ.superclass != None:
                    m_targ.superclass = self.mapAndConvertType(targ.superclass, targs, source_class, method_args, source_method)
                u_typeargs.append(m_targ)
            else:
                u_typeargs.append(targ)
        ut.coit.typeargs = u_typeargs
        return ut
            
            
        
            
            
    def mapTypeArgument(self, targ):
        if not isinstance(targ, TypeArgument):
            print "Unexpected "
            some_method()
        if targ.typ == None:
            if targ.extends != None:
                if SHelper.isTypeParameter(targ.extends):
                    tp = self.getTypeParameterWithName(targ.extends.name)
                    if tp == None:
                        print "Type Parameter not found", targ.extends.name
                        some_method()
                        
                    nt = Type()
                    nt.coit = ClassOrInterfaceType()
                    nt.coit.fullname = targ.extends.name
                    nt.coit.clazz = tp
                    return nt
                elif SHelper.isTypeParameterRec(targ.extends):
                    print "Recursing parameters not handled"
                    some_method()
            if targ.superclass != None:
                if SHelper.isTypeParameter(targ.superclass):
                    tp = self.getTypeParameterWithName(targ.superclass.name)
                    if tp == None:
                        print "Type Parameter not found", targ.extends.name
                        some_method()
                        
                    nt = Type()
                    nt.coit = ClassOrInterfaceType()
                    nt.coit.fullname = targ.superclass.name
                    nt.coit.clazz = tp
                    return nt
                elif SHelper.isTypeParameterRec(targ.superclass):
                    print "Recursing parameters not handled"
                    some_method()
        else:
            if SHelper.isTypeParameter(targ.typ):
                tp = self.getTypeParameterWithName(targ.typ.coit.fullname)
                if tp == None:
                        print "Type Parameter not found", targ.extends.name
                        some_method()
                        
                nt = Type()
                nt.coit = ClassOrInterfaceType()
                nt.coit.fullname = tp.name
                nt.coit.clazz = tp
                return nt
            elif SHelper.isTypeParameterRec(targ.typ):
                print "Recursing parameters not handled"
                some_method()
    def getImplementedMethodEx(self, am):
        for m in self.exmembers:
            if not isinstance(m, ExMethod):continue
            if m.method.isAbstract() or am.method.name != m.method.name:continue
            if len(m.pars) != len(am.pars):continue
            count = 0
            all_matched = True
            for p in m.pars:
                p1 = am.pars[count]
                count += 1
                if not SHelper.matchType(p.typ, p1.typ):
                    if SHelper.matchTypeForMethod(p.typ, p1.typ, m.method, am.method):
                        continue
                    all_matched = False
                    break
            if all_matched:
                return m
        return None              
    def checkMethodImplementation(self):
        for m in self.exmembers:
            if not isinstance(m, ExMethod):continue
            if m.method.isAbstract():
                im = self.getImplementedMethodEx(m)
                
                if im == None:
                    im = self.getImplementedMethodEx(m)
                    print self.fullname, "does not implement ", m.method.name, " from ", m.method.clazz.fullname
                    some_method()
                if im.imid == None:
                    im.imid = []
                if not (m in  im.imid):
                    im.imid.append(m)
                #TODO:Following is necessory for unused code removal
                if WAFConfig.isRemoveUnusedCode() == True:
                    im = im.method
                    if im.imid == None:
                        im.imid = []
                    if not (m in  im.imid):
                        im.imid.append(m.method)                    
                


class SEnum(STypeDeclaration):
    def __init__(self):
        STypeDeclaration.__init__(self)
        self.constants = []
        self.constants_hash = {}
        self.constructors = []
        self.exmethods_processed = False
    def isEnum(self):return True
    def processInheritance(self):
        ex = self.exclass[0]
        SHelper.processSClass(ex)
        for x in ex.symbols:self.symbols[x] = 1        
        self.constructor_count = ex.constructor_count
    def processExMembers(self):
        if self.exmethods_processed == True:return
        self.exmethods_processed = True
        count = 0
        for ex in self.implclass:
            ex.processExMembers()
            targs = self.implements[count].coit.typeargs
            if targs != None and len(targs) > 0:
                targ_count = 0
                for targ in targs:
                    targ.ref = ex.typepars[targ_count]
                    targ_count += 1
            count += 1
            for m in ex.exmembers:
                if isinstance(m, ExField):
                    if SHelper.isTypeParameterRec(m.type):
                        nf = ExField()
                        nf.field = m.field
                        if SHelper.isTypeParameterRec(m.type):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.type, targs, ex, None, None)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nf.type = mapped_type
                        else:
                            nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                    else:
                        nf = ExField()
                        nf.field = m.field
                        nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                elif isinstance(m, ExMethod):
                    if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)) or SHelper.parametersContainsTypeParameter(m.pars):
                        nm = ExMethod()
                        nm.method = m.method
                        if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.rtype, targs, ex, m.method._typepars, m.method)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nm.rtype = mapped_type
                        else:nm.rtype = m.rtype
                        if SHelper.parametersContainsTypeParameter(m.pars):
                            npars = []
                            for p in m.pars:
                                if SHelper.isTypeParameterRec(p.typ):
                                    mapped_type = None
                                    if targs != None and len(targs) > 0:
                                        mapped_type = self.mapAndConvertType(p.typ, targs, ex, m.method._typepars, m.method)
                                    else:
                                        mapped_type = SGlobal.objclass.mytype
                                    np = Parameter()
                                    np.modifier = p.modifier
                                    np.name = p.name
                                    np.isellipsis = p.isellipsis
                                    np.typ = mapped_type
                                    npars.append(np)
                                else:
                                    npars.append(p)
                            nm.pars = npars
                        else:
                            nm.pars = m.pars
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                    else:
                        nm = ExMethod()
                        nm.method = m.method
                        nm.pars = m.pars
                        nm.rtype = m.rtype
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                else:
                    print "Unexpeted"
                    print "Not handled "
                    some_method()
        implicit_pars = []
        ip = Parameter()
        ip.name = Token("_n", -1, -1)
        ip.modifiers = []
        ip.typ = SGlobal.stringclass.mytype
        implicit_pars.append(ip)
        ip = Parameter()
        ip.name = Token("_i", -1, -1)
        ip.modifiers = []
        ip.typ = SGlobal.basictypes[Literal.INT]
        implicit_pars.append(ip)
        
        for m in self.methods:
            if m.name == self.name:
                m.index = self.constructor_count
                if WAFConfig.isMinify():
                    m.js_name = self.getShortSymbolToUse();
                else:
                    m.js_name = self.getFullSymbolToUse("_c")                
                self.constructor_count += 1
                self.constructors.append(m)
                m.pars = implicit_pars + m.pars
        for c in self.constructors:
            self.methods.remove(c)#remove from normal methods
        if len(self.constructors) == 0:
            m = SMethod()
            m.setDeclaringClass(self)
            m.index = 0
            if WAFConfig.isMinify():
                m.js_name = self.getShortSymbolToUse();
            else:
                m.js_name = self.getFullSymbolToUse("_c")
            
            self.constructor_count += 1
            self.constructors.append(m)
            m.pars = implicit_pars + m.pars
            #m.setDefaultConstructor(True)
        for m in self.methods:
            m.processTypeparameters()
            nm = ExMethod()
            nm.rtype = m.rettype
            nm.pars = m.pars
            nm.method = m
            im = self.getImplementedMethodEx(nm)
            if im == None:
                if WAFConfig.isMinify():
                    m.js_name = self.getShortSymbolToUse();
                else: 
                    m.js_name = self.getFullSymbolToUse(m.name)
                
            else:
                SGlobal.addOverideRef(m,nm.method)                
                m.js_name = im.method.js_name                
            self.exmembers.append(nm)
        for m in self.fields:
            f = self.fields[m]
            nf = ExField()
            nf.type = f.type
            nf.field = f
            self.exmembers.append(nf)
    """
    def getImplementedMethodEx(self, am):
        for m in self.exmembers:
            if not isinstance(m, ExMethod):continue
            if m.method.isAbstract() or am.method.name != m.method.name:continue
            if len(m.pars) != len(am.pars):continue
            count = 0
            all_matched = True
            for p in m.pars:
                p1 = am.pars[count]
                count += 1
                if not SHelper.matchType(p.typ, p1.typ):
                    all_matched = False
                    break
            if all_matched:
                return m
        return None
    """        
    def getConstructor(self, args, accessing_class):
        for c in self.constructors:
            if c.matchArgs(args, None) == True:
                return c
        all_degrees = []
        for m in self.constructors:
            if not SHelper.canIAccessYou(m, accessing_class, False):continue
            d = m.matchArgsAndGetDegree(args, None)
            if d != None:
                all_degrees.append([d, m])
        no_of_methods = len(all_degrees)
        if no_of_methods == 0:
            return None
        if no_of_methods == 1:return all_degrees[0][1]
        minda = []
        for i in range(len(args)):minda.append(-1)
        SHelper.getMinDegreeArray(all_degrees, 0, minda, len(args))
        mind_methods = []
        for i in range(0, no_of_methods):
            if SHelper.compareDegreeArray(all_degrees[i][0], minda, len(args)):
                m = all_degrees[i][1]
                mind_methods.append(all_degrees[i][1])
        if len(mind_methods) == 1:
            return mind_methods[0]
        min_level = 100000
        for m in mind_methods:
            if m.level < min_level:min_level = m.level
        final_methods = []
        for m in mind_methods:
            if m.level == min_level:
                final_methods.append(m)
        if len(final_methods) == 1:
            return final_methods[0]        
    
        return None

class SAnnotation():
    def __init__(self):
        self.name=None
        self.value=None
class SAnnotationType(STypeDeclaration):
    def __init__(self):
        STypeDeclaration.__init__(self)
    def isAnnotationType(self):return True


class SClass(STypeDeclaration):
    def __init__(self):
        STypeDeclaration.__init__(self)
        self.constructors = []
        self.constructor_count = 0
        self.exmethods_processed = False    
    def isClass(self):return True

    def getConstructor(self, args, accessing_class):
        for c in self.constructors:
            if c.matchArgs(args, None) == True:
                return c
        all_degrees = []
        for m in self.constructors:
            if not SHelper.canIAccessYou(m, accessing_class, False):continue
            d = m.matchArgsAndGetDegree(args, None)
            if d != None:
                all_degrees.append([d, m])
        no_of_methods = len(all_degrees)
        if no_of_methods == 0:
            return None
        if no_of_methods == 1:return all_degrees[0][1]
        minda = []
        for i in range(len(args)):minda.append(-1)
        SHelper.getMinDegreeArray(all_degrees, 0, minda, len(args))
        mind_methods = []
        for i in range(0, no_of_methods):
            if SHelper.compareDegreeArray(all_degrees[i][0], minda, len(args)):
                m = all_degrees[i][1]
                mind_methods.append(all_degrees[i][1])
        if len(mind_methods) == 1:
            return mind_methods[0]
        min_level = 100000
        for m in mind_methods:
            if m.level < min_level:min_level = m.level
        final_methods = []
        for m in mind_methods:
            if m.level == min_level:
                final_methods.append(m)
        if len(final_methods) == 1:
            return final_methods[0]        
    
        return None

    def processInheritance(self):
        oc = None
        no_explicit_inheritance = False
        for t in self.extends:
            SHelper.processType(t, self, None)
        if len(self.extends) == 0 and self.fullname != "java.lang.Object":
            no_explicit_inheritance = True
            oc= SGlobal.objclass
            if oc==None:
                oc = SHelper.getClassOnFullName("java.lang.Object")
            SHelper.processSClass(oc)            
            self.addExtendedType(oc.mytype)
        for t in self.implements:#scls.implements is a typelist
            SHelper.processType(t, self, None)
            # inheritance extends
        if len(self.extends) == 1 or no_explicit_inheritance == True:
            t = self.extends[0]
            ex = None
            if no_explicit_inheritance == False:
                name = SHelper.getCoitNamesToString(t.coit)
                ex = SHelper.getClassOnNameFromImported(name, self)
            else:
                ex = oc
            self.exclass.append(ex)
            SHelper.processSClass(ex)
            for x in ex.symbols:self.symbols[x] = 1            
            self.constructor_count = ex.constructor_count


        for t in self.implements:#scls.implements is a typelist
            cls = SHelper.getClassOnNameFromImported(t.coit.fullname, self)
            if cls == None:
                print "Not found class ", t.coit.fullname
                some_method()
            SHelper.processSInterface(cls)
            self.implclass.append(cls)


    def addMethod(self, method):
        self.methods.append(method)
    """
    def processExMembersForExCreator(self):
        for m in self.methods:
            found=False
            for exm in self.exmembers:
                if isinstance(exm,ExMethod):
                    if exm.method==m: 
                        found=True 
                        break
            if found==True:continue
            nm = ExMethod()
            nm.rtype = m.rettype
            nm.pars = m.pars
            nm.method = m
            self.exmembers.append(nm)
    """
    def processExMembers(self):
        if self.exmethods_processed == True:return
        self.exmethods_processed = True
        if len(self.exclass) == 1:
            ex = self.exclass[0]
            ex.processExMembers()
            targs = self.extends[0].coit.typeargs
            if targs != None and len(targs) > 0:
                targ_count = 0
                for targ in targs:
                    targ.ref = ex.typepars[targ_count]
                    targ_count += 1
                
            for m in ex.exmembers:
                if isinstance(m, ExField):
                    if SHelper.isTypeParameterRec(m.type):
                        nf = ExField()
                        nf.field = m.field
                        if SHelper.isTypeParameterRec(m.type):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.type, targs, ex, None, None)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nf.type = mapped_type
                        else:
                            nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                    else:
                        nf = ExField()
                        nf.field = m.field
                        nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                elif isinstance(m, ExMethod):
                    if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)) or SHelper.parametersContainsTypeParameter(m.pars):
                        nm = ExMethod()
                        nm.method = m.method
                        if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.rtype, targs, ex, m.method._typepars, m.method)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nm.rtype = mapped_type
                        else:nm.rtype = m.rtype
                        if SHelper.parametersContainsTypeParameter(m.pars):
                            npars = []
                            for p in m.pars:
                                if SHelper.isTypeParameterRec(p.typ):
                                    mapped_type = None
                                    if targs != None and len(targs) > 0:
                                        mapped_type = self.mapAndConvertType(p.typ, targs, ex, m.method._typepars, m.method)
                                    else:
                                        mapped_type = SGlobal.objclass.mytype
                                    np = Parameter()
                                    np.modifier = p.modifier
                                    np.name = p.name
                                    np.isellipsis = p.isellipsis
                                    np.typ = mapped_type
                                    npars.append(np)
                                else:
                                    npars.append(p)
                            nm.pars = npars
                        else:
                            nm.pars = m.pars
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                    else:
                        nm = ExMethod()
                        nm.method = m.method
                        nm.pars = m.pars
                        nm.rtype = m.rtype
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                else:
                    print "Unexpeted"
                    print "Not handled "
                    sys.exit()
        count = 0
        for ex in self.implclass:
            ex.processExMembers()
        
            targs = self.implements[count].coit.typeargs
            if targs != None and len(targs) > 0:
                targ_count = 0
                for targ in targs:
                    targ.ref = ex.typepars[targ_count]
                    targ_count += 1
            count += 1
            for m in ex.exmembers:
                if isinstance(m, ExField):
                    if SHelper.isTypeParameterRec(m.type):
                        nf = ExField()
                        nf.field = m.field
                        if SHelper.isTypeParameterRec(m.type):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.type, targs, ex, None, None)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nf.type = mapped_type
                        else:
                            nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                    else:
                        nf = ExField()
                        nf.field = m.field
                        nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                elif isinstance(m, ExMethod):
                    if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)) or SHelper.parametersContainsTypeParameter(m.pars):
                        nm = ExMethod()
                        
                        nm.method = m.method
                        if (m.rtype != None and SHelper.isTypeParameterRec(m.rtype)):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.rtype, targs, ex, m.method._typepars, m.method)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nm.rtype = mapped_type
                        else:nm.rtype = m.rtype
                        if SHelper.parametersContainsTypeParameter(m.pars):
                            npars = []
                            for p in m.pars:
                                if SHelper.isTypeParameterRec(p.typ):
                                    mapped_type = None
                                    if targs != None and len(targs) > 0:
                                        mapped_type = self.mapAndConvertType(p.typ, targs, ex, m.method._typepars, m.method)
                                    else:
                                        mapped_type = SGlobal.objclass.mytype
                                    np = Parameter()
                                    np.modifier = p.modifier
                                    np.name = p.name
                                    np.isellipsis = p.isellipsis
                                    np.typ = mapped_type
                                    npars.append(np)
                                else:
                                    npars.append(p)
                            nm.pars = npars
                        else:
                            nm.pars = m.pars
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                    else:
                        nm = ExMethod()
                        nm.method = m.method
                        nm.pars = m.pars
                        nm.rtype = m.rtype
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                else:
                    print "Unexpeted"
                    print "Not handled "
                    some_method()
        for m in self.methods:
            if m.name == self.name:
                m.index = self.constructor_count
                if WAFConfig.isMinify():
                    m.js_name = self.getShortSymbolToUse();
                else:
                    m.js_name = self.getFullSymbolToUse("_c")
                
                self.constructor_count += 1
                self.constructors.append(m)
        for c in self.constructors:
            self.methods.remove(c)#remove from normal methods
        if len(self.constructors) == 0:
            m = SMethod()
            m.setDeclaringClass(self)
            m.index = 0
            if WAFConfig.isMinify():
                m.js_name = self.getShortSymbolToUse();
            else:
                m.js_name = self.getFullSymbolToUse("_c")
            
            self.constructor_count += 1
            self.constructors.append(m)
            m.setDefaultConstructor(True)
        
        for m in self.methods:
            nm = ExMethod()            
            nm.rtype = m.rettype
            nm.pars = m.pars
            nm.method = m
            if m.getAnnotation("NoJavaScript"):
                #if self.symbols.has_key(m.name):
                #    raise Exception("Symbol Not Available for Use "+m.name+" in "+self.fullname)
                m.js_name=m.name
                self.symbols[m.name]=1                                
            else:
                im = self.getImplementedMethodEx(nm)
                if im == None:
                    if WAFConfig.isMinify():
                        if m.getAnnotation("EnsureIdentifier"):
                            if not self.canIUseThisSymbol(m.name):
                                raise Exception("Can not ensure the symbol "+m.name+" "+self.fullname) 
                            self.addSymbol(m.name)
                            m.js_name=m.name
                        else:
                            m.js_name = self.getShortSymbolToUse();
                    else:
                        if self.fullname=="java.lang.String":
                            m.js_name = self.getFullSymbolToUse("_"+m.name)
                        else:
                            if m.getAnnotation("EnsureIdentifier"):
                                if not self.canIUseThisSymbol(m.name):
                                    raise Exception("Can not ensure the symbol "+m.name+" "+self.fullname) 
                                self.addSymbol(m.name)
                                m.js_name=m.name
                            else:
                                m.js_name = self.getFullSymbolToUse(m.name)
                    
                else:
                    m.js_name = im.method.js_name            
            self.exmembers.append(nm)
        for m in self.fields:
            f = self.fields[m]
            nf = ExField()
            nf.type = f.type
            nf.field = f
            self.exmembers.append(nf)
        
        

    
    
    """
    def getImplementedMethodEx(self, am):
        for m in self.exmembers:
            if not isinstance(m, ExMethod):continue
            if m.method.isAbstract() or am.method.name != m.method.name:continue
            if len(m.pars) != len(am.pars):continue
            count = 0
            all_matched = True
            for p in m.pars:
                p1 = am.pars[count]
                count += 1
                if not SHelper.matchType(p.typ, p1.typ):
                    all_matched = False
                    break
            if all_matched:
                return m
        return None
    """


class ExMethod:
    def __init__(self):
        self.rtype = None
        self.pars = []
        self.method = None
        self.level = 0
        self.imid = None
    def matchArgsModifiedPars(self, pars, args, class_type_args, cls, method_type_args):
        if len(args) != len(pars):return None
        l = len(args)
        for i in range(0, l):
            p = pars[i]
            if SHelper.isTypeParameterRec(p):
                clz = cls
                if clz == None:
                    clz = self.method.clazz                
                p = clz.mapAndConvertType(p, class_type_args, cls, method_type_args, self.method)                
            if not SHelper.matchType(p, args[i]):
                return False
        return True
    def matchArgs(self, args, class_type_args, cls, method_type_args):
        if len(args) != len(self.pars):return None
        l = len(args)
        for i in range(0, l):
            p = self.pars[i].typ
            if SHelper.isTypeParameterRec(p):
                clz = cls
                if clz == None:
                    clz = self.method.clazz                
                p = clz.mapAndConvertType(p, class_type_args, cls, method_type_args, self.method)                
            if not SHelper.matchType(p, args[i]):
                return False
        return True
    def matchArgsAndGetDegreeModifiedPars(self, pars, args, class_type_args, cls, method_type_args):
        if len(args) != len(pars):return None
        l = len(args)
        ds = []
        for i in range(0, l):
            p = pars[i]
            if SHelper.isTypeParameterRec(p):
                clz = cls
                if clz == None:
                    clz = self.method.clazz                
                p = clz.mapAndConvertType(p, class_type_args, cls, method_type_args, self.method)        
            d = SHelper.matchTypeAndGetDegree(args[i], p)
            if d < 0:return None
            ds.append(d)
        return ds
    def matchArgsAndGetDegree(self, args, class_type_args, cls, method_type_args):
        if len(args) != len(self.pars):return None
        l = len(args)
        ds = []
        for i in range(0, l):
            p = self.pars[i].typ
            if SHelper.isTypeParameterRec(p):
                clz = cls
                if clz == None:
                    clz = self.method.clazz                
                p = clz.mapAndConvertType(p, class_type_args, cls, method_type_args, self.method)        
            d = SHelper.matchTypeAndGetDegree(args[i], p)
            if d < 0:return None
            ds.append(d)
        return ds
class ExField:
    def __init__(self):
        self.type = None
        self.field = None
        self.level = 0
        

    






#######


####333







class SInterface(STypeDeclaration):
    def __init__(self):
        STypeDeclaration.__init__(self)
        self.exmethods_processed = False
    def isInterface(self):return True
    def processInheritance(self):
        for t in self.extends:
            SHelper.processType(t, self, None)
            exclass = t.coit.clazz
            SHelper.processSInterface(exclass)#
            for x in exclass.symbols:self.symbols[x] = 1            
            self.exclass.append(exclass)
    def processExMembers(self):
        if self.exmethods_processed == True:return
        self.exmethods_processed = True
        count = 0
        for ex in self.exclass:
            ex.processExMembers()
            targs = self.extends[count].coit.typeargs
            if targs != None and len(targs) > 0:
                targ_count = 0
                for targ in targs:
                    targ.ref = ex.typepars[targ_count]
                    targ_count += 1
            count += 1
            for m in ex.exmembers:
                if isinstance(m, ExField):
                    if SHelper.isTypeParameterForClassRec(m.type):
                        nf = ExField()
                        nf.field = m.field
                        if SHelper.isTypeParameterForClassRec(m.type):
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.type, targs, ex, None, None)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nf.type = mapped_type
                        else:
                            nf.type = m.type
                        self.exmembers.append(nf)
                        nf.level = m.level + 1
                    else:
                        nf = ExField()
                        nf.field = m.field
                        nf.type = m.type
                        nf.level = m.level + 1
                        self.exmembers.append(nf)
                elif isinstance(m, ExMethod):
                    if (m.rtype != None and SHelper.isTypeParameterForClassRec(m.rtype)) or SHelper.parametersContainsTypeParameterForClass(m.pars):
                        nm = ExMethod()
                        nm.method = m.method
                        if (m.rtype != None and SHelper.isTypeParameterForClassRec(m.rtype)):                            
                            mapped_type = None
                            if targs != None and len(targs) > 0:
                                mapped_type = self.mapAndConvertType(m.rtype, targs, ex, m.method._typepars, m.method)
                            else:
                                mapped_type = SGlobal.objclass.mytype
                            nm.rtype = mapped_type
                        else:nm.rtype = m.rtype
                        if SHelper.parametersContainsTypeParameterForClass(m.pars):
                            npars = []
                            for p in m.pars:
                                if SHelper.isTypeParameterForClassRec(p.typ):
                                    mapped_type = None
                                    if targs != None and len(targs) > 0:
                                        mapped_type = self.mapAndConvertType(p.typ, targs, ex, m.method._typepars, m.method)
                                    else:
                                        mapped_type = SGlobal.objclass.mytype
                                    np = Parameter()
                                    np.modifier = p.modifier
                                    np.name = p.name
                                    np.isellipsis = p.isellipsis
                                    np.typ = mapped_type
                                    npars.append(np)
                                else:
                                    npars.append(p)
                            nm.pars = npars
                        else:
                            nm.pars = m.pars
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                    else:
                        nm = ExMethod()
                        nm.method = m.method
                        nm.pars = m.pars
                        nm.rtype = m.rtype
                        nm.level = m.level + 1
                        self.exmembers.append(nm)
                else:
                    print "Unexpeted"
                    print "Not handled "
                    sys.exit()
        for m in self.methods:
            nm = ExMethod()
            nm.rtype = m.rettype
            nm.pars = m.pars
            nm.method = m
            self.exmembers.append(nm)
        for m in self.fields:
            m=self.fields[m]
            nf = ExField()
            nf.type = m.type
            nf.field = m
            self.exmembers.append(nf)



class SMember(HasModifiers):
    MEMBER_COUNTER = 0
    def __init__(self):
        HasModifiers.__init__(self)
        self.clazz = None
        self.name = None
        self.js_name = None        
        self.mid = SMethod.MEMBER_COUNTER
        SMethod.MEMBER_COUNTER += 1
    def getJSName(self):
        if self.js_name == None:
            print self.clazz.fullname
            print self.name
            raise Exception("js name not assigned ") 
        return self.js_name    
    def getDeclaringClass(self):return self.clazz
    def setDeclaringClass(self, clazz):self.clazz = clazz
    def getName(self):return self.name
    def setName(self, name):self.name = name

class SMethod(SMember):
    
    def __init__(self):
        SMember.__init__(self)
        self.pars = []
        self.rettype = None
        self.typepars = []
        self._typepars = None
        self.throws = []
        self.is_void = False
        self.index = False
        self.method = None
        self.native_code = None
        self.imid = None##implemented method id this can be from interface  or abstract class
        self.default_constructor = False
        self.refs = []
        self.calls_model=False
    def callsModel(self):
        return self.calls_model
    def isDefaultConstructor(self):
        return self.default_constructor
    def setDefaultConstructor(self, value):
        self.default_constructor = value
    def isVoid(self):
        return self.is_void
    def setVoid(self, value):
        self.is_void = value
    def getReturnType(self):
        return self.rettype
    def setReturnTyoe(self, typ):
        self.rettype = typ
    def getParameterTypes(self):
        return self.pars
    def setParameterTypes(self, pars):
        self.pars = pars
    def getExceptionTypes(self):
        return self.throws
    def setExceptionTypes(self, throws):
        self.throws = throws
    def hasTypePars(self):
        return len(self.typepars) > 0
    def getTypePars(self): return self.typepars
    def setTypePars(self, typepars):
        self.typepars = typepars
    def getTypeParameterWithName(self, name):
        if self.typepars != None:
            for t in self.typepars:
                if t.name.data == name: return t
        return self.clazz.getTypeParameterWithName(name)
    def getTypeParameterWithNameNonRec(self, name):
        if self.typepars != None:
            for t in self.typepars:
                if t.name.data == name: return t
        return None
    def processTypeparameters(self):
        if self.typepars != None:
            for tp in self.typepars:
                SHelper.processTypeParameter(tp, self, None)
        self.processTypePars()
    def processTypePars(self):
        if self.typepars == None:return
        self._typepars = []
        for tpar in self.typepars:
            ta = TypeArgument()
            ta.isany = False
            t = self.convertTypeParameterToTypePass1(tpar)
            ta.typ = t
            self._typepars.append(ta)
        for t in self._typepars:
            self.convertTypeParameterToTypePass2(ta.typ)
    def convertTypeParameterToTypePass2(self, t):
        if not SHelper.isTypeParameterRec(t):
            return  t
        if t.coit != None:
            clz = t.coit.clazz
            if isinstance(clz, TypeParameter):
                tp = clz
                tp_clz = None
                if tp.forclass != None:
                    tp_clz = tp.forclass
                else:
                    tp_clz = tp.formethod
                return tp_clz._typepars[tp.index]
            #Type argument has to be there
            n_typeargs = []
            for arg in t.coit.typeargs:
                atype = None
                if arg.isany == True:
                    if arg.extends == None and arg.superclass == None:
                        atype = SGlobal.objclass.mytype
                    elif arg.extends != None:
                        atype = arg.extends
                    else:
                        atype = arg.superclass
                    arg.superclass
                else:
                    if arg.typ == None: print "UnExpected", some_method()
                    atype = arg.typ
                    if arg.extends != None or arg.superclass != None:
                        print "UnExpected", some_method()
                _arg = self.convertTypeParameterToTypePass2(atype)
                n_typeargs.append(_arg)
            t.coit.typeargs = n_typeargs
        else:
            #This should have bounds
            n_bounds = []
            for b in t.bounds:
                _b = self.convertTypeParameterToTypePass2(b)
                n_bounds.append(_b)
            t.bounds = n_bounds
        return t
                
            
        
    def convertTypeParameterToTypePass1(self, tp):
        if not isinstance(tp, TypeParameter):
            print "UnExpected"
            some_method()
        if tp.bound == None:
            return SGlobal.objclass.mytype
        if len(tp.bound) == 1:
            #it has single bound
            b = tp.bound[0]
            if SHelper.isTypeParameter(b):
                # and that is another type , you can have another type paramater as multiple bounds 
                rt = Type()
                rt.bounds = []
                rt.bounds.append(b)
                return rt
            else:
                return b
        rt = Type()
        rt.bounds = []
        for b in tp.bound:
            rt.bounds.append(b)
        return rt
    def matchArgs(self, args, method_type_args):
        if len(args) != len(self.pars):return None
        l = len(args)
        for i in range(0, l):
            p1 = self.pars[i]
            if not SHelper.matchType(p1.typ, args[i]):
                return False
        return True
    def matchArgsAndGetDegree(self, args, method_type_args):
        if len(args) != len(self.pars):return None
        l = len(args)
        ds = []
        for i in range(0, l):
            p1 = self.pars[i]
            d = SHelper.matchTypeAndGetDegree(args[i], p1.typ)
            if d < 0:return None
            ds.append(d)
        return ds

        #TODO:incomplete

    def matchPars(self, pars):
        if len(pars) != len(self.pars):return False
        l = len(pars)
        if l == 0:return True
        match_count = 0
        for i in range(0, l):
            p1 = self.pars[i]
            p2 = pars[i]
            #p1=Parameter()
            #p2=Parameter()
            if SHelper.matchType(p1.typ, p2.typ):
                if p1.isellipsis == p2.isellipsis:
                    match_count += 1
        return match_count == l

class SField(SMember):
    def __init__(self):
        SMember.__init__(self)
        self.type = None
        self.field = None
        self.init = None
    def getType(self):
        return self.type
    def setType(self, t):
        self.type = t
    def getJSName(self):
        if WAFConfig.isMinify():
            return self.js_name
        else:
            return self.js_name

class SGlobal:
    chars_saved=0
    hashes={}
    libpaths = []
    processed_files = {}
    processed_scu = {}
    root = SPackage()
    objclass = None
    clientclass=None
    autobxingclass=None
    throwable_class=None
    json_sr_cls=None
    method_fromJSON=None
    method_toJSON=None
    arrayclass = None
    basictypes = None
    wrappertypes = None
    stringclass = None
    static_code_calls = []
    static_field_lines = []
    necessory_classes_processed = False
    static_refs = []
    method_refs = {}
    processed_refs = []
    class_refs = {}
    omid={}
    used_methods = []
    css_vars = {}
    wafmodel = None
    wafcontroller = None
    async_callback =None
    async_on_success=None
    async_on_failure=None
    compiling_controller=False
    @staticmethod
    def initJSON():
        if SGlobal.json_sr_cls==None:
            SGlobal.json_sr_cls=SHelper.getClassOnFullName("com.openwaf.server.JSONSerializable")
            if SGlobal.json_sr_cls==None:
                raise Exception("Can not fin class com.openwaf.server.JSONSerializable")
            for m in SGlobal.json_sr_cls.methods:
                if m.name=="fromJSON":
                    SGlobal.method_fromJSON=m
                if m.name=="toJSON":
                    SGlobal.method_toJSON=m        
    @staticmethod
    def addOverideRef(my,parent):
        if not SGlobal.omid.has_key(parent.mid):
            SGlobal.omid[parent.mid]=[]
        SGlobal.omid[parent.mid].append(my)
                
    @staticmethod
    def addCssVar(cname, vname, value):
        h = None
        if cname == None:
            if SGlobal.css_vars.has_key("_D_"):
                h = SGlobal.css_vars["_D_"]
            else:
                h = {}
                SGlobal.css_vars["_D_"] = h
        else:
            if SGlobal.css_vars.has_key(cname):
                h = SGlobal.css_vars[cname]
            else:
                h = {}
                SGlobal.css_vars[cname] = h
        if h.has_key(vname):
            raise Exception("Duplicate Variable found in same scope:" + cname + ",Var Name:" + vname + " ")
        h[vname] = value
    @staticmethod
    def getCssVar(cname, vname):
        h = None
        if cname == None:
            if not SGlobal.css_vars.has_key["_D_"]:
                raise Exception("Not variable found for global scope ")            
            h = SGlobal.css_vars["_D_"]
        else:
            if not SGlobal.css_vars.has_key(cname):
                raise Exception("Not variable found for scope " + cname)
            h = SGlobal.css_vars[cname]
        return h
                
                
                
    
        
        
    @staticmethod
    def addStaticFieldLine(line):
        SGlobal.static_field_lines.append(line)
    @staticmethod
    def addStaticCodeCall(line):
        SGlobal.static_code_calls.append(line)
    @staticmethod
    def initWarraperTypes():
        if SGlobal.wrappertypes != None:return
        SGlobal.wrappertypes = {}
        cls = SHelper.getClassOnFullName("java.lang.Character")
        SGlobal.wrappertypes[PrimitiveType.CHAR] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Double")
        SGlobal.wrappertypes[PrimitiveType.DOUBLE] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Boolean")
        SGlobal.wrappertypes[PrimitiveType.BOOLEAN] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Float")
        SGlobal.wrappertypes[PrimitiveType.FLOAT] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Integer")
        SGlobal.wrappertypes[PrimitiveType.INT] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Long")
        SGlobal.wrappertypes[PrimitiveType.LONG] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Byte")
        SGlobal.wrappertypes[PrimitiveType.BYTE] = cls.mytype
        cls = SHelper.getClassOnFullName("java.lang.Short")
        SGlobal.wrappertypes[PrimitiveType.SHORT] = cls.mytype
        SGlobal.wafmodel = SHelper.getClassOnFullName("com.openwaf.core.framework.WAFModel")
        if SGlobal.wafmodel==None:
            print "WAFModel class not found",some_method()
        SGlobal.wafcontroller = SHelper.getClassOnFullName("com.openwaf.core.framework.WAFController")
        if SGlobal.wafcontroller==None:
            print "WAFController class not found",some_method()
        SGlobal.async_callback=SHelper.getClassOnFullName("com.openwaf.core.framework.AsyncCallback")
        if SGlobal.async_callback==None:
            print "AsycnCallback class not found",some_method()
        
        
    @staticmethod
    def initBasicType():
        if SGlobal.basictypes != None:return
        SGlobal.basictypes = {}
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.CHAR)
        SGlobal.basictypes[PrimitiveType.CHAR] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.DOUBLE)
        SGlobal.basictypes[PrimitiveType.DOUBLE] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.BOOLEAN)
        SGlobal.basictypes[PrimitiveType.BOOLEAN] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.FLOAT)
        SGlobal.basictypes[PrimitiveType.FLOAT] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.INT)
        SGlobal.basictypes[PrimitiveType.INT] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.LONG)
        SGlobal.basictypes[PrimitiveType.LONG] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.NULL)
        SGlobal.basictypes[PrimitiveType.NULL] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.BYTE)
        SGlobal.basictypes[PrimitiveType.BYTE] = t
        t = Type()
        t.pm_type = PrimitiveType(PrimitiveType.SHORT)
        SGlobal.basictypes[PrimitiveType.SHORT] = t

        SGlobal.stringclass = SHelper.getClassOnFullName("java.lang.String")


    @staticmethod
    def getBasicTypeForLiteral(l):
        SGlobal.initBasicType()
        if l.typ == Literal.CHAR:
            data = None
            value = None
            if isinstance(l.value, str):data = l.value
            else: data = l.value.data
            if len(data) == 3:
                value = ord(data[1])
            else:
                data = data[1:-1]
                if len(data) == 2 and data[0] == "\\":
                    if data == "\\n":value = ord('\n')
                    elif data == "\\b":value = ord('\b')
                    elif data == "\\f":value = ord('\f')
                    elif data == "\\t":value = ord('\t')
                    elif data == "\\r":value = ord('\r')
                    else:value = ord(data[1])
                elif data.lower().startswith("\u"):
                    value = int(data[2:], 16)
                else:
                    print "Not handled ", data
                    some_method()
            return SGlobal.basictypes[PrimitiveType.CHAR]
        if l.typ == Literal.DOUBLE:
            return SGlobal.basictypes[PrimitiveType.DOUBLE]
        if l.typ == Literal.FALSE or l.typ == Literal.TRUE:
            return SGlobal.basictypes[PrimitiveType.BOOLEAN]
        if l.typ == Literal.FLOAT:
            return SGlobal.basictypes[PrimitiveType.FLOAT]
        if l.typ == Literal.INT:
            data = None
            if isinstance(l.value, str):data = l.value
            else:data = l.value.data
            value = None
            if data.lower().startswith("0x"):
                value = int(data[2:], 16)
                if len(data[2:]) == 8 and int(data[2:3], 16) > 7:
                    ##http://stackoverflow.com/questions/319199/why-is-java-able-to-store-0xff000000-as-an-int
                    value = value & Literal.MAX_INT
                    value = value - 2147483648; 
            else:
                value = int(data, 10)
            return SGlobal.basictypes[PrimitiveType.INT]
        if l.typ == Literal.LONG:
            return SGlobal.basictypes[PrimitiveType.LONG]
        if l.typ == Literal.NULL:
            return SGlobal.basictypes[PrimitiveType.NULL]
        if l.typ == Literal.STRING:
            return SGlobal.stringclass.mytype
        print l.typ
        some_method()#just to throw exception
    @staticmethod
    def getBasicTypeForLiteral2(l):
        SGlobal.initBasicType()
        if l.typ == Literal.CHAR:
            data = None
            value = None
            if isinstance(l.value, str):data = l.value
            else: data = l.value.data
            if len(data) == 3:
                value = ord(data[1])
            else:
                data = data[1:-1]
                if len(data) == 2 and data[0] == "\\":
                    if data == "\\n":value = ord('\n')
                    elif data == "\\b":value = ord('\b')
                    elif data == "\\f":value = ord('\f')
                    elif data == "\\t":value = ord('\t')
                    elif data == "\\r":value = ord('\r')
                    else:value = ord(data[1])
                elif data.lower().startswith("\u"):
                    value = int(data[2:], 16)
                else:
                    print "Not handled ", data
                    some_method()
            if value < 256:
                return SGlobal.basictypes[PrimitiveType.BYTE]
            return SGlobal.basictypes[PrimitiveType.CHAR]
        if l.typ == Literal.DOUBLE:
            return SGlobal.basictypes[PrimitiveType.DOUBLE]
        if l.typ == Literal.FALSE or l.typ == Literal.TRUE:
            return SGlobal.basictypes[PrimitiveType.BOOLEAN]
        if l.typ == Literal.FLOAT:
            return SGlobal.basictypes[PrimitiveType.FLOAT]
        if l.typ == Literal.INT:
            data = None
            if isinstance(l.value, str):data = l.value
            else:data = l.value.data
            value = None
            if data.lower().startswith("0x"):
                value = int(data[2:], 16)
                if len(data[2:]) == 8 and int(data[2:3], 16) > 7:
                    ##http://stackoverflow.com/questions/319199/why-is-java-able-to-store-0xff000000-as-an-int
                    value = value & Literal.MAX_INT
                    value = value - 2147483648; 
            else:
                value = int(data, 10)
            if value < 256:
                return SGlobal.basictypes[PrimitiveType.BYTE]
            if value < 65536:
                return SGlobal.basictypes[PrimitiveType.SHORT]
            return SGlobal.basictypes[PrimitiveType.INT]
        if l.typ == Literal.LONG:
            return SGlobal.basictypes[PrimitiveType.LONG]
        if l.typ == Literal.NULL:
            return SGlobal.basictypes[PrimitiveType.NULL]
        if l.typ == Literal.STRING:
            return SGlobal.stringclass.mytype
        print l.typ
        some_method()#just to throw exception

    @staticmethod
    def getBasicTypeForPrimitiveType(p):
        SGlobal.initBasicType()
        return SGlobal.basictypes[p.value]





class SHelper:
    id_chars=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    @staticmethod
    def getCharForNumber(v):
        import Compiler
        print "XXX "+str(v), 
        if v>=52:
            r=v%52
            d=(v-r)/52
            rv=SHelper.getCharForNumber(d)+SHelper.id_chars[r]
            if Compiler.isKeyword(rv):
                print "_"+rv
                return "_"+rv
            print rv
            return rv
        else:
            rv=SHelper.id_chars[v]
            if Compiler.isKeyword(rv):
                print "_"+rv
                return "_"+rv
            print rv
            return rv         
                
    @staticmethod
    def parametersContainsTypeParameter(pars):
        for p in pars:
            if SHelper.isTypeParameterRec(p.typ):return True
        return False
    @staticmethod
    def isTypeParameterRec(t, processed=None):
        if processed == None:
            processed = []
        if isinstance(t, Type):
            if t in processed:
                return False
            processed.append(t)
            if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
                processed.pop()
                return True
            if t.coit != None and t.coit.typeargs != None and len(t.coit.typeargs) > 0:
                for targ in t.coit.typeargs:
                    if SHelper.isTypeParameterRec(targ, processed):
                        processed.pop()
                        return True                   
            if t.coit != None and t.coit.clazz == SGlobal.arrayclass:
                r = SHelper.isTypeParameterRec(t.coit.next, processed)
                processed.pop()
                return r
            if t.bounds != None:
                for b in t.bounds:
                    if b in processed:continue
                    if b in processed:
                        processed.pop()
                        return False
                    processed.append(b)
                    if SHelper.isTypeParameterRec(b, processed):
                        processed.pop()
                        processed.pop()
                        return True
                    processed.pop()
            processed.pop()
            return False
        if isinstance(t, TypeArgument):
            if t.typ != None:
                if SHelper.isTypeParameterRec(t.typ, processed):
                    return True
            if t.extends != None:
                if SHelper.isTypeParameterRec(t.extends, processed):
                    return True
            if t.superclass != None:
                if SHelper.isTypeParameterRec(t.superclass, processed):
                    return True
            return False
            
        
        print "UnExpected"
        print t
        some_method()
            
        return False

    @staticmethod
    def isTypeParameter(t):
        if not isinstance(t, Type):
            print t
            some_method()#just to cause exception
        if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
            return True
        return False

    @staticmethod
    def parametersContainsTypeParameterForClass(pars):
        for p in pars:
            if SHelper.isTypeParameterForClassRec(p.typ):return True
        return False
    @staticmethod
    def isTypeParameterForClassRec(t, processed=None):
        if processed == None:
            processed = []
        if isinstance(t, Type):
            if t in processed:
                return False
            processed.append(t)
            if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
                r = t.coit.clazz.forclass != None
                processed.pop()
                return r
            if t.coit != None and t.coit.typeargs != None and len(t.coit.typeargs) > 0:
                for targ in t.coit.typeargs:
                    if SHelper.isTypeParameterForClassRec(targ, processed):
                        processed.pop()
                        return True                   
            if t.coit != None and t.coit.clazz == SGlobal.arrayclass:
                r = SHelper.isTypeParameterForClassRec(t.coit.next, processed)
                processed.pop()
                return r
            if t.bounds != None:
                for b in t.bounds:
                    if b in processed:continue
                    if b in processed:
                        processed.pop()
                        return False
                    processed.append(b)
                    if SHelper.isTypeParameterForClassRec(b, processed):
                        processed.pop()
                        processed.pop()
                        return True
                    processed.pop()
            processed.pop()
            return False
        if isinstance(t, TypeArgument):
            if t.typ != None:
                if SHelper.isTypeParameterForClassRec(t.typ, processed):
                    return True
            if t.extends != None:
                if SHelper.isTypeParameterForClassRec(t.extends, processed):
                    return True
            if t.superclass != None:
                if SHelper.isTypeParameterForClassRec(t.superclass, processed):
                    return True
            return False
            
        
        print "UnExpected"
        print t
        some_method()
            
        return False

    @staticmethod
    def isTypeParameterForClass(t):
        if not isinstance(t, Type):
            print t
            some_method()#just to cause exception
        if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
            return t.coit.clazz.forclass != None
        return False
    @staticmethod
    def parametersContainsTypeParameterForMethod(pars):
        for p in pars:
            if SHelper.isTypeParameterForMethod(p.typ):return True
        return False
    @staticmethod
    def isTypeParameterForMethodRec(t, processed=None):
        if processed == None:
            processed = []
        if isinstance(t, Type):
            if t in processed:
                return False
            processed.append(t)
            if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
                r = t.coit.clazz.formethod != None
                processed.pop()
                return r
            if t.coit != None and t.coit.typeargs != None and len(t.coit.typeargs) > 0:
                for targ in t.coit.typeargs:
                    if SHelper.isTypeParameterForMethodRec(targ, processed):
                        processed.pop()
                        return True                   
            if t.coit != None and t.coit.clazz == SGlobal.arrayclass:
                r = SHelper.isTypeParameterForMethodRec(t.coit.next, processed)
                processed.pop()
                return r
            if t.bounds != None:
                for b in t.bounds:
                    if b in processed:
                        continue
                    if b in processed:
                        processed.pop()
                        return False
                    processed.append(b)
                    if SHelper.isTypeParameterForMethodRec(b, processed):
                        processed.pop()
                        processed.pop()
                        return True
                    processed.pop()
            processed.pop()
            return False
        if isinstance(t, TypeArgument):
            if t.typ != None:
                if SHelper.isTypeParameterForMethodRec(t.typ, processed):
                    return True
            if t.extends != None:
                if SHelper.isTypeParameterForMethodRec(t.extends, processed):
                    return True
            if t.superclass != None:
                if SHelper.isTypeParameterForMethodRec(t.superclass, processed):
                    return True
            return False
            
        
        print "UnExpected"
        print t
        some_method()
            
        return False
    @staticmethod
    def isTypeParameterForMethod(t):
        if not isinstance(t, Type):
            print t
            some_method()#just to cause exception
        if t.coit != None and isinstance(t.coit.clazz, TypeParameter):
            return t.coit.clazz.formethod != None
        return False

    """
        compares two type
        fullname should be resolved by the container class
    """
    @staticmethod
    def ttos(p):
        if type(p).__name__ == 'instance':
            return p.__class__.__name__
        else:
            return  type(p).__name__
    @staticmethod
    def getMinDegreeArray(ms, pos, fdegree, arg_count):
        method_count = len(ms)
        nms = []
        mind = ms[0][0][pos]
        for i in range(0, method_count):
            mind = min(mind, ms[i][0][pos])
        fdegree[pos] = mind
        for i in range(0, method_count):
            if ms[i][0][pos] == mind:
                nms.append(ms[i])
        if pos + 1 == arg_count:return        
        SHelper.getMinDegreeArray(nms, pos + 1, fdegree, arg_count)
    @staticmethod
    def compareDegreeArray(d1, d2, count):
        for i in range(0, count):
            if d1[i] != d2[i]:return False
        return True

    @staticmethod
    def getPrimitiveTypeDegree(v1, v2):
        """
        Please Refer to 
        http://en.wikibooks.org/wiki/Java_Programming/Types
        http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html
        Following found to be wrong in case of byte to char conversion ..
        REF:http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/Chapter02/castsMixing.html
        C - indicates that an explicit cast is required since the precision is decreasing.
        A - indicates that the precision is increasing so an automatic cast occurs without the need for an explicit cast.
        N - indicates that the conversion is not allowed.
        * - asterisk indicates that the least significant digits may be lost in the conversion even though the target type allows for bigger numbers
            int    long    float    double    char    byte    short    boolean
        int    -    A    A*    A    C    C    C    N
        long    C    -    A*    A*    C    C    C    N
        float    C    C    -    A    C    C    C    N
        double    C    C    C    -    C    C    C    N
        char    A    A    A    A    -    C    C    N
        byte    A    A    A    A    C    -    A    N
        short    A    A    A    A    C    C    -    N
        boolean    N    N    N    N    N    N    N    -
        """
        if v1 == v2:return 0
        if v1 == PrimitiveType.INT:
            if v2 == PrimitiveType.LONG:return 1
            if v2 == PrimitiveType.FLOAT:return 2
            if v2 == PrimitiveType.DOUBLE:return 3
        if v1 == PrimitiveType.LONG:
            if v2 == PrimitiveType.FLOAT:return 1
            if v2 == PrimitiveType.DOUBLE:return 2
        if v1 == PrimitiveType.FLOAT:
            if v2 == PrimitiveType.DOUBLE:return 1
        if v1 == PrimitiveType.CHAR:
            if v2 == PrimitiveType.INT:return 1
            if v2 == PrimitiveType.LONG:return 2
            if v2 == PrimitiveType.FLOAT:return 3
            if v2 == PrimitiveType.DOUBLE:return 4
        if v1 == PrimitiveType.BYTE:
            if v2 == PrimitiveType.SHORT:return 1
            if v2 == PrimitiveType.INT:return 2
            if v2 == PrimitiveType.LONG:return 3
            if v2 == PrimitiveType.FLOAT:return 4
            if v2 == PrimitiveType.DOUBLE:return 5
        if v1 == PrimitiveType.SHORT:
            if v2 == PrimitiveType.INT:return 1
            if v2 == PrimitiveType.LONG:return 2
            if v2 == PrimitiveType.FLOAT:return 3
            if v2 == PrimitiveType.DOUBLE:return 4
        return -1


    @staticmethod
    def matchTypeAndGetDegree(t1, t2):
        if isinstance(t1, Type) and isinstance(t2, Type):
            if t1.pm_type != None and t1.pm_type.value == PrimitiveType.NULL and t2.coit != None:
                return 1000
            if t1.pm_type != None  and t2.coit !=None and t2.coit.clazz==SGlobal.objclass:
                return 2000                
            if (t1.pm_type == None and t2.pm_type != None) or (t1.pm_type != None and t2.pm_type == None):
                _t1 = t1
                _t2 = t2
                if t1.pm_type != None:
                    if not Semantic.SA.isWrapperClass(t2):return None
                    SGlobal.initWarraperTypes()
                    _t1 = SGlobal.wrappertypes[t1.pm_type.value]
                    v = _t1.coit.clazz.getDegreeWithThis(t2.coit.clazz)
                    if v != None:
                        return v + 10
                else:
                    if not Semantic.SA.isWrapperClass(t1):return None
                    SGlobal.initWarraperTypes()
                    _t2 = SGlobal.wrappertypes[t2.pm_type.value]
                    v = _t2.coit.clazz.getDegreeWithThis(t1.coit.clazz)
                    if v != None:
                        return v + 10
                return None
            if t1.pm_type != None:
                if t1.pm_type.value == t2.pm_type.value:return 0
                return SHelper.getPrimitiveTypeDegree(t1.pm_type.value, t2.pm_type.value)
            #if t1.arraydim != None and t2.arraydim != None:
            #    if t1.arraydim != t2.arraydim:return None
            if t1.coit != None and t2.coit == None:return None
            if t1.coit == None and t2.coit != None:return None
            if t1.coit != None:
                if t1.coit.clazz != None and t2.coit.clazz != None:
                    if isinstance(t1.coit.clazz, TypeParameter) and isinstance(t2.coit.clazz, TypeParameter):
                        if t1.coit.clazz == t2.coit.clazz:
                            return 0
                        return t1.coit.clazz.getDegreeWithThis(t2.coit.clazz)
                    elif  isinstance(t1.coit.clazz, TypeParameter) or isinstance(t2.coit.clazz, TypeParameter):
                        if (not isinstance(t1.coit.clazz, TypeParameter)) or t1.coit.clazz.bound == None:
                            return 0
                        else:
                            return t2.coit.clazz.getDegreeWithThis(t1.coit.clazz.bound.coit.clazz)
                    else:
                        if t1.coit.clazz == SGlobal.arrayclass and t2.coit.clazz == SGlobal.arrayclass:
                            return SHelper.matchType(t1.coit.next, t2.coit.next)
                        return t1.coit.clazz.getDegreeWithThis(t2.coit.clazz)
        return -1

    @staticmethod
    def matchTypeForMethod(t1, t2, m1, m2):
        if not (t1.coit != None and t2.coit != None):return False
        if not (t1.coit.clazz != None and t2.coit.clazz != None):return False
        if t1.coit.clazz == SGlobal.arrayclass and t2.coit.clazz == SGlobal.arrayclass:
            return SHelper.matchTypeForMethod(t1.coit.next, t2.coit.next, m1, m2)
        if isinstance(t1.coit.clazz, TypeParameter) and isinstance(t2.coit.clazz, TypeParameter):
            if t1.coit.clazz.formethod == m1 and t2.coit.clazz.formethod == m2 and t1.coit.clazz.index == t2.coit.clazz.index:
                return True
        return False
    @staticmethod
    def matchType(t1, t2):
        #if isinstance(t1, TypeParameter) and isinstance(t2, Type):
        #    return (t2.coit != None and t2.coit.clazz == t1)
        #elif isinstance(t2, TypeParameter) and isinstance(t1, Type):
        #    return (t1.coit != None and t1.coit.clazz == t2)
        if isinstance(t2, TypeParameter) and isinstance(t1, TypeParameter):
            return t1 == t2;
        elif isinstance(t1, Type) and isinstance(t2, Type):
            if t1.pm_type == None and t2.pm_type != None:return False
            if t1.pm_type != None and t2.pm_type == None:return False
            if t1.pm_type != None:
                if t1.pm_type.value != t2.pm_type.value:return False
            #if t1.arraydim != None and t2.arraydim != None:
            #    if t1.arraydim != t2.arraydim:return False
            if t1.coit != None and t2.coit == None:return False
            if t1.coit == None and t2.coit != None:return False
            if t1.coit != None:
                if t1.coit.clazz != None and t2.coit.clazz != None:
                    if isinstance(t1.coit.clazz, TypeParameter) and isinstance(t2.coit.clazz, TypeParameter):
                        if t1.coit.clazz == t2.coit.clazz:
                            return True
                        #if t2.coit.clazz.formethod != None and t1.coit.clazz.formethod != None:#THIS IS Wrong
                        #    return True
                    if t1.coit.clazz == SGlobal.arrayclass and t2.coit.clazz == SGlobal.arrayclass:
                        return SHelper.matchType(t1.coit.next, t2.coit.next)
                    if isinstance(t1.coit.clazz, STypeDeclaration) and isinstance(t2.coit.clazz, STypeDeclaration): 
                        if t1.coit.fullname == t2.coit.fullname:
                            return True
                        else:
                            return False
                    else:
                        return False
                            
                        #print "FNC ",t1.coit.fullname,t2.coit.fullname
                    return False
            #TODO:compare type arguments
            return True
        return None
    @staticmethod
    def getImportedAll(imported, curPackage):
        toR = {}
        r = SHelper.getImported("java.lang.*")
        for name in r:
            toR[name] = r[name]
        if curPackage != None:
            r = SHelper.getImported(curPackage + ".*")
            if r!=None:
                for name in r:
                    toR[name] = r[name]
        for i in imported:
            r = SHelper.getImported(i)
            if r!=None:
                for name in r:
                    toR[name] = r[name]

        for p in SGlobal.root.subpackages:
            toR[p] = SGlobal.root.subpackages[p]
        for t in SGlobal.root.types:
            toR[t] = SGlobal.root.subpackages[t]
        return toR



    @staticmethod
    def getImported(imp):
        parts = imp.split(".")
        l = len(parts)

        if parts[l - 1] == "*":
            p = SHelper.getPackage(parts, 0, l - 1, SGlobal.root)
            if p==None:return None
            return p.types
        else:
            p = SHelper.getPackage(parts, 0, l - 1, SGlobal.root)
            if p==None:return None
            if isinstance(p, SPackage):
                if not p.types.has_key(parts[l - 1]):
                    return None                    
                r = {}
                r[parts[l - 1]] = p.types[parts[l - 1]]
                return r
            else:
                r = {}
                r[p.name] = p
                return r

    @staticmethod
    def getPackage(parts, i, l, curPack):
        if i == l:return curPack
        if curPack.subpackages.has_key(parts[i]):
            return SHelper.getPackage(parts, i + 1, l, curPack.subpackages[parts[i]])
        if curPack.types.has_key(parts[i]):
            return SHelper.getInnerClass(parts, i + 1, l + 1, curPack.types[parts[i]])
        return None
    @staticmethod
    def getInnerClass(parts, i, l, curClass):
        if i == l:return curClass
        inner = curClass.getInnerMember(parts[i])
        if inner == None:
            print " Inner class not found in import " + parts[i] + " " + curClass.getFullname()
            some_method()
        return SHelper.getInnerClass(parts, i + 1, l, inner)
        
    @staticmethod
    def processSEnum(scls):
        #scls=SEnum()
        if scls.processed == True:return
        scls.scu.processImports()
        scls.setProcessed(True)
        scls.exclass = []
        scls.exclass.append(SHelper.getClassOnFullName("java.lang.Enum"))
        scls.processInheritance()
        scls.processFields()
        scls.processMethods()
        scls.processInnerMembers()
        
        
        for name in scls.constants_hash:
            const = scls.constants_hash[name]
            f = SField()
            f.setName(name)
            f.setDeclaringClass(scls)
            f.modifiers = []
            f.addModifier(SModifier.PUBLIC)
            f.addModifier(SModifier.STATIC)
            f.setType(scls.mytype)
            if WAFConfig.isMinify():
                f.js_name = scls.getShortSymbolToUse();
            else:
                f.js_name = scls.getFullSymbolToUse(name)            
            exp = Expression()
            exc = ExCreator()
            exc.creator = Creator()
            exc.creator.typ = scls.mytype.coit
            exc.creator.ccr = ClassCreatorRest()
            ccr = exc.creator.ccr;
            if const.args == None:
                ccr.args = []
            else:
                ccr.args = const.args
            ######
            aex1 = Expression()
            lits = ExLiteral()
            lits.literal = Literal(Literal.STRING, "\"" + name + "\"")
            aex1.parts = [lits]
            aex2 = Expression()
            liti = ExLiteral()
            liti.literal = Literal(Literal.INT, str(const.index))
            aex2.parts = [liti]
            ccr.args = [aex1, aex2] + ccr.args
            ######
            ccr.body = const.classbody
            exp.parts = [exc]
            f.init = exp
            scls.addField(f)
        scls.processExMembers()
            
        
        #since abstract methods can be implemented in enum instance creation
        #//DEEPAK(2){public int get(int n){return this.hello();};},
        #//PATIL(3){public int get(int n){return n;};}; 
        #if not scls.isAbstract():
        #    scls.checkMethodImplementation()
        #scls.mytype.coit.typeargs = scls._typepars
        
        
        
                

    @staticmethod
    def processSClass(scls):
        if SGlobal.arrayclass == None:
            SGlobal.arrayclass = SHelper.getClassOnFullName("java.lang.Array")
            if SGlobal.arrayclass == None:
                SGlobal.arrayclass = SHelper.getClassOnFullName("java.lang.Array")
                raise  Exception("Array class not found")                            
            SHelper.processSClass(SGlobal.arrayclass)
        if scls.processed == True:return
        scls.scu.processImports()
       
        if scls.fullname == "java.lang.Object":
            scls.symbols["_clz"] = 1 # points protoype of current class
            scls.symbols["_pi"] = 1  # points to container class in case of innerClasses and anonymous instance creation
            scls.symbols["_ac"] = 1  # proxy for abstract method call
            scls.symbols["_id"] = 1  # unique id to class
            scls.symbols["_i"] = 1   # contains ids of classes which are currently held use in instanceof and type casting
            scls.symbols["_p"] = 1   # for prototype
            scls.symbols["isDisabled"] = 1   # bug is IE9 we are not using this
            if SGlobal.objclass != None:return
            SGlobal.objclass = scls
        scls.setProcessed(True)
        scls.processTypeparameters()
        scls.processInheritance()
        scls.processFields()
        scls.processMethods()
        scls.processInnerMembers()
        scls.processExMembers()
        if not scls.isAbstract():
            scls.checkMethodImplementation()
        scls.mytype.coit.typeargs = scls._typepars
        

    @staticmethod
    def mapTypeArguments(currentClass, current_typeargs, t, targetclass):
        mapped_typeargs = []
        current_class_with_no_type_args = True
        if current_typeargs == None or len(current_typeargs) == 0:
            current_class_with_no_type_args = False
        if targetclass.typepars != None and len(targetclass.typepars) > 0:
            if t.coit.typeargs != None and len(t.coit.typeargs) > 0:
                for arg in t.coit.typeargs:
                    if arg.typ.coit.clazz == None:
                        name = arg.typ.coit.fullname
                        if current_class_with_no_type_args == False:
                            print "Can not map type argument", name
                            some_method()
                        matched_par = None
                        for tp in current_typeargs:
                            if tp.name.data == name:
                                matched_par = tp
                                break
                        if matched_par == None:
                            print "Type Argument Diddnt matched", name
                            some_method()
                        mapped_typeargs.append(matched_par)
                    else:
                        mapped_typeargs.append(arg.typ)

            else:
                for t in targetclass.typepars:
                    mapped_typeargs.append(SGlobal.objclass)

        return mapped_typeargs






    @staticmethod
    def processSInterface(scls):
        if SGlobal.arrayclass == None:
            SGlobal.arrayclass = SHelper.getClassOnFullName("java.lang.Array")
            SHelper.processSClass(SGlobal.arrayclass)
        if scls.processed == True:return
        scls.scu.processImports()
        scls.setProcessed(True)
        scls.processTypeparameters()
        scls.processInheritance()
        scls.processFields()
        scls.processMethods()
        scls.processExMembers()
        scls.mytype.coit.typeargs = scls._typepars



    @staticmethod
    def getSCUForPackage(package_str):#TODO:check this i guess used from outside module
        tor = []
        for f in SGlobal.processed_files:
            scu = SGlobal.processed_files[f]
            if scu.package == package_str:
                tor.append(scu)
        return tor

    @staticmethod
    def getClassOnFullName(name):
        parts = name.split(".")
        return SHelper.getClassOnFullNameImpl(parts, 0, len(parts) - 1, SGlobal.root)
    @staticmethod
    def getClassOnFullNameImpl(parts, i, l, curPack):
        if i == l:
            if curPack.types.has_key(parts[i]):
                return curPack.types[parts[i]]
            if curPack.subpackages.has_key(parts[i]):
                return curPack.subpackages[parts[i]]
            return None
        if curPack.subpackages.has_key(parts[i]):
            value = SHelper.getClassOnFullNameImpl(parts, i + 1, l, curPack.subpackages[parts[i]])
            if value != None:return value
        if i + 1 == l and curPack.types.has_key(parts[i]):
            t = curPack.types[parts[i]]
            value = t.getInnerMember(parts[i + 1])
            return value
        return None

    @staticmethod
    def getClassOnNameFromImported(name, scls):
        #print "CONFI:",name
        if name == None:return None
        if scls.scu.imported.has_key(name):
            return scls.scu.imported[name]
        if "." in name:
            cls = SHelper.getClassOnFullName(name)
            if cls != None:
                return cls
            parts = name.split(".")
            if scls.scu.imported.has_key(parts[0]):
                cls = scls.scu.imported[parts[0]]
                return SHelper.getInnerClass(parts, 1, len(parts) , cls)
        r = scls.getInnerMember(name)
        if r != None:return r
        r = scls.getOuterMember(name)
        if r != None:return r
        return None
    @staticmethod
    def isEndsWith(path, name):
        l = len(path)
        if l == len(name):
            if path == name:
                return True
        elif path.endswith(name):
            pos = l - len(name) - 1
            if path[pos] == ".":
                return True
        return False
    
    @staticmethod
    def processTypeParameter(t, scls , method):
        if t.bound == None:return
        for b in t.bound:
            SHelper.processType(b, scls, method)
    @staticmethod
    def processTypeArgument(t, scls, m):
        if t.isany == False and t.typ != None:
            SHelper.processType(t.typ, scls, m)
            #t.typ.coit.fullname=SHelper.getCoitNamesToString(t.typ.coit)
            #t.typ.coit.clazz=None
        if t.extends != None:
            SHelper.processType(t.extends, scls, m)
        if t.superclass != None:
            SHelper.processType(t.superclass, scls, m)

    @staticmethod
    def processType(t, scls, method):
        if not isinstance(t, Type):
            print t
            print "UnExpected", some_method()
        if t.processed == True:
            return
        t.processed = True
        if isinstance(t, Type) and t.arraydim > 0:
            nt = Type()
            nt.arraydim = t.arraydim - 1
            t.arraydim = 0
            nt.pm_type = t.pm_type
            nt.coit = t.coit
            coit = ClassOrInterfaceType()
            coit.clazz = SGlobal.arrayclass
            coit.fullname = SGlobal.arrayclass.fullname
            coit.next = nt
            t.coit = coit
            t.pm_type = None
            SHelper.processType(nt, scls, method)
            return
        coit = None
        coit = t.coit
        
        
        if coit == None:return
        if coit.clazz == SGlobal.arrayclass:
            return
        SHelper.updateFullNameForCOIT(coit, scls, method)
        #if coit.clazz==None:
        #    name=SHelper.getCoitNamesToString(t.coit)

        if coit.clazz == None and method != None:
            name = SHelper.getCoitNamesToString(coit)
            tp = method.getTypeParameterWithName(name)
            if tp == None:
                tp = method.getTypeParameterWithName(name)
            else:
                coit.fullname = name
                coit.clazz = tp
        if coit.clazz == None and scls != None:
            name = SHelper.getCoitNamesToString(coit)
            tp = scls.getTypeParameterWithName(name)
            if tp==None and (name=="JSONObject" or name=="JSONArray"):
                name="java.lang.Object"
                tp=SGlobal.objclass
            if tp == None:
                print "Problem  Type parameter not found 2",name,scls.fullname
                tp = scls.getTypeParameterWithName(name)
                SHelper.updateFullNameForCOIT(coit, scls, method)
                print coit.fullname, name
                some_method()
            coit.fullname = name
            coit.clazz = tp
        if coit.typeargs == None:return
        if len(coit.typeargs) == 0:return
        if coit.clazz.typepars == None:
            #TODO:throw exception
            print coit.fullname, " dosent have any Type Parameters "
            some_method()
        if len(coit.typeargs) != len(coit.clazz.typepars):
            #TODO:throw exception
            print coit.fullname, " should have ", len(coit.clazz.typepars), " Type Parameter(s)"
            some_method()
        for ta in coit.typeargs:
            SHelper.processTypeArgument(ta, scls, method)
        #TODO:need to check type bounds here

    @staticmethod
    def updateFullNameForCOIT(coit, scls, method):
        name = SHelper.getCoitNamesToString(coit)
        if name == None:return
        if name == scls.getName():
            coit.fullname = scls.fullname
            coit.clazz = scls
            return
        cls = SHelper.getClassOnNameFromImported(name, scls)
        if cls != None:
            coit.fullname = cls.fullname
            coit.clazz = cls
            return
        if cls == None:
            if "." in name:
                parts = name.split(".")
                ccls = SHelper.getClassOnNameFromImported(parts[0], scls)
                if ccls == None:
                    print "Not found ", name
                    some_method()
                cls = SHelper.getClassForDottedString(parts, 0, ccls)
                coit.fullname = cls.fullname
                coit.clazz = cls
                return
        return

    @staticmethod
    def getClassForDottedString(parts, ci, ccls):
        if len(parts) == (ci + 1):
            print "Tottaly unexpected", parts
            some_method()
        name = parts[ci + 1]
        if isinstance(ccls, STypeDeclaration):
            rcls = ccls.getInnerMember(name)
            if rcls == None:
                print "Not found ", name, " in ", ".".join(parts)
                some_method()
            if len(parts) == ci + 2:
                return rcls
            return SHelper.getClassForDottedString(parts, ci + 1, rcls)
        elif isinstance(ccls, SPackage):
            rcls = None
            if ccls.subpackages.has_key(name):
                return SHelper.getClassForDottedString(parts, ci + 1, ccls.subpackages[name])
            if not ccls.types.has_key(name):
                print "Not found ", name, " in ", ".".join(parts)
                some_method()
            rcls = ccls.types[name]
            if len(parts) == ci + 2:
                return rcls
            return SHelper.getClassForDottedString(parts, ci + 1, rcls)
        else:
            print "Unknown thing to handle ", parts, name
            some_method()

    @staticmethod
    def processFile(filepath):
        if SGlobal.processed_files.has_key(filepath):
            return SGlobal.processed_files[filepath]
        SGlobal.processed_files[filepath] = "__PROCESSING__"
        cu = Compiler.processJavaFile(filepath)
        SGlobal.processed_files[filepath] = cu
        return cu
    @staticmethod
    def processCompilationUnit(cu, model=False,controller=False):
        package_str = "_d_" #default package
        if cu.package != None:
            package_str = SHelper.qualifiedNameToString(cu.package)
        [d, s, fname] = cu.filepath.rpartition('\\');
        key = package_str + fname
        scu = None
        if SGlobal.processed_scu.has_key(key):
            return SGlobal.processed_scu[key]
        else:
            scu = SCompilationUnit()
            SGlobal.processed_scu[key] = scu
        scu.package = package_str
        scu.filepath = cu.filepath
        SGlobal.processed_files[scu.filepath] = scu
        imported = []

        if model == False:
            for i in cu.imports:
                imported.append(SHelper.importToString(i))
        else:
            imported.append("com.openwaf.core.framework.WAFModel")
            imported.append("com.openwaf.core.framework.AsyncCallback")
            imported.append("java.util.*")
            imported.append("java.lang.*")
            for i in cu.imports:
                i=SHelper.importToString(i)
                if i.startswith("shared."):
                    imported.append(i)
        scu.imported = imported
        #decls could be Class,Enum,Interface
        for d in cu.decl:
            cls = None
            if isinstance(d, Class):
                cls = SHelper.processClass(d, package_str, scu,False,model,controller)
            elif isinstance(d, Interface):
                if model == False:
                    cls = SHelper.processInterface(d, package_str, scu)
                else:continue
            elif isinstance(d, AnnotationType):
                if model == False:
                    cls = SHelper.processAnnotationType(d, package_str, scu)
                else:continue
            elif isinstance(d, Enum):
                if model == False:
                    cls = SHelper.processEnum(d, package_str, scu)
                else:continue
            else:
                print "Not handled in processCompilationUnit", SHelper.ttos(d)
                some_method()
            #cls.setDeclaringClass(cls)
            scu.delcs.append(cls)
        scu.annotations = cu.annotations
        return scu

    @staticmethod
    def getCoitNamesToString(coit):
        if not (isinstance(coit, ClassOrInterfaceType) and coit.names != None):return None
        strings = []
        for name in coit.names:
            strings.append(name.data)
        return ".".join(strings)
    @staticmethod
    def qualifiedNameToString(qf):
        s = ""
        for name in qf.names:
            s += name.data + "."
        return s[:-1]#skip last .

    @staticmethod
    def importToString(im):
        #TODO:static is ignored here
        s = ""
        for name in im.names:
            s += name.data + "."
        if im.isstar == True:
            return s + "*"
        return s[:-1]

    



    @staticmethod
    def processInterface(cls, package_str, scu, processingInner=False):
        i = SInterface()
        i.setAnnotations(SHelper.getAnnotations(cls.modifiers))
        i.setModifiers(SHelper.getModifiers(cls.modifiers))
        i.setName(cls.name.data)
        i.setTypepars(cls.typepars)
        if cls.extends != None:
            for e in cls.extends:
                i.addExtendedType(e)
        i.setPackage(package_str)
        
        if len(package_str) > 0:
            i.setFullname(package_str + "." + i.name)
        else:
            i.setFullname(i.name)
        i.setCompilationUnit(scu)
        i.setInner(processingInner)
        mt = Type()
        mt.coit = ClassOrInterfaceType()
        mt.coit.fullname = i.fullname
        mt.coit.clazz = i
        i.setMyType(mt)
        for cb in cls.body:
            if isinstance(cb, InterfaceField):
                fields = SHelper.readFields(cb, i)
                for f in fields:
                    f.setDeclaringClass(i)
                    f.addModifier(SModifier.PUBLIC)
                    f.addModifier(SModifier.STATIC)
                    i.addField(f)
            elif isinstance(cb, InterfaceMethod):
                m = SHelper.readMethod(cb)
                m.addModifier(SModifier.PUBLIC)
                m.addModifier(SModifier.ABSTRACT)
                m.setDeclaringClass(i)
                i.addMethod(m)
            elif isinstance(cb, Class):
                ic = SHelper.processClass(cb, package_str + "." + i.name, scu, True)
                i.addInnerMember(ic)
            elif isinstance(cb, Interface):
                ii = SHelper.processInterface(cb, package_str + "." + i.name, scu, True)
                i.addInnerMember(ii)
            elif isinstance(cb, Enum):
                ii = SHelper.processEnum(cb, package_str + "." + i.name, scu, True)
                i.addInnerMember(ii)
            elif isinstance(cb, StaticBlock):
                i.addStaticBlock(cb)
            else:
                print Semantic.SA.ttos(cb)
                print "INCOMPLETE_COMPILATION:Inner member not processed",
                some_method()
        if not processingInner:
            SHelper.addClassToPackageTree(package_str + "." + i.name, i)
        return i

    @staticmethod
    def processAnnotationType(cls, package_str, scu, processingInner=False):
        sc = SAnnotationType()
        sc.setAnnotations(SHelper.getAnnotations(cls.modifiers))
        sc.setModifiers(SHelper.getModifiers(cls.modifiers))
        sc.setName(cls.name.data)
        sc.setPackage(package_str)
        if len(package_str) > 0:
            sc.setFullname(package_str + "." + sc.name)
        else:
            sc.setFullname(sc.name)
        sc.setCompilationUnit(scu)
        sc.setInner(processingInner)
        #TODO:process it
        if not processingInner:
            SHelper.addClassToPackageTree(sc.fullname, sc)
        return sc
    @staticmethod
    def processEnum(cls, package_str, scu, processingInner=False):
        #TODO:check this
        e = SEnum()
        e.setName(cls.name.data)
        if len(package_str) > 0:
            e.setFullname(package_str + "." + e.name)
        else:
            e.setFullname(e.name)
        e.setAnnotations(SHelper.getAnnotations(cls.modifiers))
        e.setModifiers(SHelper.getModifiers(cls.modifiers))
        e.setPackage(package_str)
        e.setInner(processingInner)
        if cls.implements != None:
            for i in cls.implements:
                e.addImplemenetedType(i)
        e.setCompilationUnit(scu)
        if cls.body != None:
            index_count = 0
            if cls.body.constants != None:
                for c in cls.body.constants:
                    name = c.name.data
                    c.index = index_count
                    index_count += 1
                    if e.constants_hash.has_key(name):
                        print "Duplicate enum values ", name
                        some_method()
                    e.constants_hash[name] = c
        if cls.implements != None:
            for i in cls.implements:
                e.addImplemenetedType(i)
        mt = Type()
        mt.coit = ClassOrInterfaceType()
        mt.coit.fullname = e.fullname
        mt.coit.clazz = e
        e.setMyType(mt)
        if cls.body.decls != None:
            for cb in cls.body.decls:
                if isinstance(cb, Field):
                    fields = SHelper.readFields(cb, e)
                    for f in fields:
                        f.setDeclaringClass(e)
                        e.addField(f)
                elif isinstance(cb, Method):
                    m = SHelper.readMethod(cb)
                    m.setDeclaringClass(e)
                    e.addMethod(m)
                elif isinstance(cb, Class):
                    ic = SHelper.processClass(cb, package_str + "." + e.name, scu, True)
                    e.addInnerMember(ic)
                elif isinstance(cb, Interface):
                    ii = SHelper.processInterface(cb, package_str + "." + e.name, scu, True)
                    e.addInnerMember(ii)
                elif isinstance(cb, Enum):
                    ie = SHelper.processEnum(cb, package_str + "." + e.name, scu, True)
                    e.addInnerMember(ie)
                elif isinstance(cb, StaticBlock):
                    e.addStaticBlock(cb)
                else:
                    print Semantic.SA.ttos(cb)
                    print "INCOMPLETE_COMPILATION:Inner member not processed",
                    some_method()
            
        if not processingInner:
            SHelper.addClassToPackageTree(package_str + "." + e.name, e)
        return e

    @staticmethod
    def processClass(cls, package_str, scu, processingInner=False, model=False,controller=False):
        sc = SClass()
        sc.model_class=model
        sc.controller_class=controller
        sc.setAnnotations(SHelper.getAnnotations(cls.modifiers))
        sc.setModifiers(SHelper.getModifiers(cls.modifiers))
        sc.setName(cls.name.data)
        sc.setTypepars(cls.typepars)
        if cls.extends != None:
            sc.addExtendedType(cls.extends)#in case of class this is not an array
        if cls.implements != None:
            for i in cls.implements:
                sc.addImplemenetedType(i)
        sc.setPackage(package_str)
        sc.setInner(processingInner)
        if len(package_str) > 0:
            sc.setFullname(package_str + "." + sc.name)
        else:
            sc.setFullname(sc.name)
        sc.setCompilationUnit(scu)
        mt = Type()
        mt.coit = ClassOrInterfaceType()
        mt.coit.fullname = sc.fullname
        mt.coit.clazz = sc
        sc.setMyType(mt)
        for cb in cls.body:
            if isinstance(cb, Field):
                if model==True:continue
                fields = SHelper.readFields(cb, sc)
                for f in fields:
                    f.setDeclaringClass(sc)
                    sc.addField(f)
            elif isinstance(cb, Method):
                m = SHelper.readMethod(cb)
                m.setDeclaringClass(sc)
                sc.addMethod(m)
            elif isinstance(cb, Class):
                if model==True:continue
                ic = SHelper.processClass(cb, package_str + "." + sc.name, scu, True)				
                sc.addInnerMember(ic)
            elif isinstance(cb, Interface):
                if model==True:continue
                ii = SHelper.processInterface(cb, package_str + "." + sc.name, scu, True)
                sc.addInnerMember(ii)
            elif isinstance(cb, Enum):
                if model==True:continue
                ii = SHelper.processEnum(cb, package_str + "." + sc.name, scu, True)				
                sc.addInnerMember(ii)
            elif isinstance(cb, StaticBlock):
                if model==True:continue
                sc.addStaticBlock(cb)
            else:
                print Semantic.SA.ttos(cb)
                print "INCOMPLETE_COMPILATION:Inner member not processed",
                some_method()
            #TODO:inner class or enum or interface not handled
            #Could be Class or Enum or Interface
        if not processingInner:
            SHelper.addClassToPackageTree(package_str + "." + sc.name, sc)
        return sc


    @staticmethod
    def extractNativeCode(code):
        # Small state machine to
        l = len(code)
        start = 0
        end = 0
        i = 0
        s = 0
        while i < l:
            if s == 0 and code[i] == "/":
                s = 1
                i += 1
                continue
            if s == 1 and code[i] == "*":
                s = 2
                i += 1
                continue
            if s == 2 and code[i] == "-":
                start = i + 1
                break
            if code[i] in ws_char:
                i += 1
                continue
            return None
        if start == 0: return None

        i = l - 1
        s = 0
        while i >= 0:
            if s == 0 and code[i] == "/":
                s = 1
                i -= 1
                continue
            if s == 1 and code[i] == "*":
                s = 2
                i -= 1
                continue
            if s == 2 and code[i] == "-":
                end = i
                break
            if code[i] in ws_char:
                i -= 1
                continue
            return None
        if end == 0: return None
        code = code[start:end].strip()
        lines = code.split("\n")
        lines = filter(lambda x:cmp (x.strip(), ""), lines)
        return lines


    @staticmethod
    def readMethod(m):
        sm = SMethod()
        sm.setAnnotations(SHelper.getAnnotations(m.modifiers))
        sm.setModifiers(SHelper.getModifiers(m.modifiers))
        sm.setTypePars(m.typepars)
        sm.setExceptionTypes(m.throws)
        sm.setReturnTyoe(m.rettyp)
        sm.setVoid(m.is_void)
        sm.setName(m.name.data)
        sm.setParameterTypes(m.pars)
        sm.method = m
        if m.native_code != None:
            sm.native_code = SHelper.extractNativeCode(m.native_code)
        return sm


    @staticmethod
    def readFields(f, cls):
        values = []
        for d in f.declarators:
            sf = SField()
            sf.setType(d.typ)
            sf.setAnnotations(SHelper.getAnnotations(f.modifiers))
            sf.setModifiers(SHelper.getModifiers(f.modifiers))
            sf.setName(d.name.data)
            sf.field = d
            sf.init = d.init
            sf.field_index = cls.field_index
            cls.field_index += 1
            values.append(sf)
        return values

    @staticmethod
    def getModifiers(mods):
        #TODO:anotations are ingnored here for time being
        values = []
        for m in mods:
            if isinstance(m, Token):
                values.append(SModifier.toConstant(m.data))
        if not (SHelper.containsModifier(values, SModifier.PUBLIC) or SHelper.containsModifier(values, SModifier.PRIVATE) or SHelper.containsModifier(values, SModifier.PROTECTED)):
            values.append(SModifier.DEFAULT)
        return values
    @staticmethod
    def getAnnotations(mods):
        values = []
        m=Annotation()
        for m in mods:
            if not isinstance(m, Token):
                v=SAnnotation()
                v.name=SHelper.qualifiedNameToString(m.name)                
                values.append(v)
        return values
        
    
    @staticmethod
    def containsModifier(mods, mod):
        if mods == None:return False
        for m in mods:
            if m == mod:return True
        return False

    @staticmethod
    def addClassToPackageTree(path, sc):
        parts = path.split(".")
        l = len(parts)
        SHelper.addClassToPackageTreeImpl(parts, 0, l - 1, SGlobal.root, sc)

    @staticmethod
    def addClassToPackageTreeImpl(parts, i, l, curPack, sc):
        if i == l:
            curPack.types[parts[i]] = sc
            return #We dont care for duplicates
        if not curPack.subpackages.has_key(parts[i]):
            sp = SPackage()
            curPack.subpackages[parts[i]] = sp
            sp.name = parts[i]
        SHelper.addClassToPackageTreeImpl(parts, i + 1, l, curPack.subpackages[parts[i]], sc)

    @staticmethod
    def canIAccessYou(member, accessing_class, only_static):
        if accessing_class == None:return True#TODO:this change is made for static members ,need to check
        dec_class = member.getDeclaringClass()
        if only_static:
            if not member.isStatic():
                return False
        if member.isPublic():return True
        if dec_class.fullname == accessing_class.fullname:return True
        if accessing_class.exclass[0].fullname == dec_class.fullname:
            if member.isProtected():
                return True
        if dec_class.getCompilationUnit().package == accessing_class.getCompilationUnit().package:
            if member.isDefault() or member.isProtected():
                return True
            if dec_class.isClassInnerToMe(accessing_class) or accessing_class.isClassInnerToMe(dec_class):
                return True
            if dec_class.scu == accessing_class.scu:
                return True
        return False
